解决C

时间:2018-11-04 15:52:50

标签: c performance onlinejudge

上部下部

Bibi还想挑战Jojo和Lili。她的字符串S的长度为N。字符串可以包含 大写和小写字符。然后,她将从字符串的开头开始迭代,如果第K个 字符是大写字符,那么她将更改其后的所有字符,例如大写 字符将变为小写,小写字符将变为大写。结束后 迭代,她会问Jojo和Lili字符串是什么。

格式输入

1。输入的第一行将包含一个整数T,即测试用例的数量。

2。每个测试用例都将包含一个字符串S和一个整数N作为长度。

格式化输出

对于每个测试用例,打印“案例#X:”(X以1开头)。然后在同一行上,在 迭代。

约束

1 <= T <= 10

1 <= N <= 100000

该字符串仅包含大写和小写字符。

这是我的解决方案。但它一直在获得TLE。

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(){
int room,len;

scanf("%d",&room);
char words[100000];

for(int i = 0; i<room; i++){
    scanf("%s %d",words,&len);
    char next[100000];
    int j = 0;

    printf("Case #%d: ",i+1);
    while(j<len){
        int k = j+1;
        if(isupper(words[j])){
            while(k<len){
                if(isupper(words[k])){
                    words[k] = tolower(words[k]);
                }else{
                    words[k] = toupper(words[k]);
                }
                k++;
            }
        }
        //printf("%c",words[j]);
        j++;
    }
    printf("%s",words);
    printf("\n");

}

return 0;
}

需要帮助以寻求更好的解决方案。

我认为TLE来自嵌套循环,但是如果没有嵌套循环,我将无法解决。

2 个答案:

答案 0 :(得分:2)

在“新算法”部门-您已按照规定实施了算法。但是,这意味着您要花费大量时间(我猜大部分时间都是在字符串中),从而可能多次更改字符的大小写。您实际上不需要这样做。保留您发现的大写字符数的计数器,该字符最初设置为零。检查字符时,请检查计数器。如果计数器为奇数(即if (counter & 1)...),请反转当前正在查看的字符的大小写(从上到下,从下到上)。完成此操作后,测试一下您当前正在查看的字符是否为大写(可能刚刚更改为大写)。如果是这样,请增加计数器。然后继续下一个字符。

这可以就地完成并一次性完成,没有任何嵌套循环。

所以您在字符串上的循环看起来像

for (i = 0, counter = 0 ; i < strlen(string) ; ++i)
  {
  if (counter & 1)                     /* if counter is odd */
    if (isupper(string[i]))            /* if character [i] is upper case */
      string[i] = tolower(string[i]);  /* convert character [i] to lower case */
    else
      string[i] = toupper(string[i]);  /* convert character [i] to upper case */

  if(isupper(string[i]))               /* if character [i] is now upper case */
    counter += 1;                      /* increment the counter */
  }

好运。

答案 1 :(得分:0)

您可以尝试使用一些指针魔术来尝试此操作。另外,请尝试将程序分成功能,以便代码的每个部分都有明确的用途。最后,scanf并不是获得用户输入的很好解决方案:如果用户输入的字符比预期的多,它将破坏您的程序(如果使用Windows,则可能会破坏您的系统)。我只是以这个scan_str为例。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

/* Helper function to swap a character case */
char swap_case(char c) {
    if(isupper(c))
        return tolower(c);

    return toupper(c);
}

/* Our iteration test case */
char*test_iterate(char*str) {
    char *p, *p0;

    /* Don't swap until first upper char is found */
    int swap = 0;

    /*
     * - Initialize both pointers to beginning of string
     * - Iterate until a 0 is found (end of string)
     * - Each iteration, "advance" pointer by one
     */
    for(p0 = p = str; *p != 0; p++) {

        /* If is upper, begin to swap case */
        if(isupper(*p))
            swap = 1;

        *p = swap ? swap_case(*p) : *p;
    }

    /* Return pointer to begining of word */
    return p0;
}

/*
 * `scanf("%s", &word)` is not good if you are serious and want to avoid memory overflow
 */
char*scan_str() {
    /* Lets begin with 10 bytes allocated */
    size_t buf_size = 10;
    char c, *word = (char*) malloc(buf_size);
    int length = 0;

    /* Iterate reading characters from `stdin` until ENTER is found */
    while( (c = getc(stdin)) != '\n' && c != EOF ) {

        /* If we need more than already allocated, allocate more (10 bytes more) */
        if((length + 1) >= buf_size) {
            buf_size += 10;
            word = realloc(word, buf_size);
            if(word == NULL)
                return "Some weird error.";
        }

        /* Save read char to our word/buffer */
        word[length] = c;
        length++;
    }

    /* Add word ending character */
    word[length] = 0;

    return word;
}

int main(void) {
    int room;

    /* Two dimensional array: list of string pointers */
    char**tests;

    /*
     * Use `scanf` to read an integer
     * It's still not good enough, as you need this weird `%*c` to discard ENTER inputs
     */
    printf("Insert number of tests to do:\n");
    scanf("%d%*c", &room);

    /* Allocate memory for `tests`: array of pointers to strings */
    tests = (char**) malloc(sizeof(char*) * room);

    /* Get input from user */
    for(int i = 0; i < room; i++) {
        printf("Insert test case #%d:\n", i + 1);
        tests[i] = scan_str();
    }

    /* Print results and free each test memory */
    for(int i = 0; i < room; i++) {
        printf("Case #%d: %s\n", i + 1, test_iterate(tests[i]) );
        free(tests[i]);
    }

    /* Free `tests` array */
    free(tests);

    return 0;
}