我的代码的时间复杂度是多少:在字符串中反转单词?我应该考虑不对称的间距吗?

时间:2017-07-25 14:12:07

标签: c string time-complexity reverse

问题陈述:编写声明void str_words_in_rev(char *input, int length)的函数,该函数反转单词/(s)字符串中的单词。我为它实现了两种不同的解决方案,其中一种非常复杂。

解决方案1:我使用void reverse(char* string, int start, int end)函数反转整个字符串,该函数获取要反转的字符串或子字符串的第一个和最后一个字母的索引。之后,我使用相同的反向函数反转字符串中的每个单词

#include<stdio.h>

void swapChar(char *a, char *b) {
  char temp = *a;
  *a = *b;
  *b = temp;
}

int length(char *string) {
  if(string == NULL)
     return -1;
  int i=0;
  for(;string[i++];);
  return i;
}

void reverse(char* string, int start, int end) {
  int mid = start + (end - start + 1)/2;
  for(int i=start,j=end;i<mid;)
    swapChar(&string[i++], &string[j--]);
}

int main() {
  char str[] = "abc def ghij klmn";
  int i=0, j=0, len = length(str), flag = 0;

  if(str == NULL || !(*str))
     return 0;
  for(;str[j]!='\0';++j) {
     if(str[j] == ' ') {
       flag = 1;
       reverse(str,i,j-1);
       i = j+1;
     }
  }
  if(flag == 1) {
  reverse(str, i, j-1);
  reverse(str,0,len-2);
  }
  printf("%s\n", str);
  return 0;
}

解决方案2:我通过使用pushToEnd函数和将每个单词和空格字符(在重新排列后)移到最后,然后在结束的单词之前移动结束< / em>的。如果我的解释不充分(我为此道歉),有一些printf语句可以被注释掉以真正理解发生了什么。

        int pushToEnd(char *str, int length) {

        int len = 0;
        int i = 0, j = 0, k = 0, n = 0;
        for (i = 0; str[i++] != ' ' && i <= length;)
            ++len;
        if (len == length)
            return len;
        //printf("Length of first word:");
        //printf("%d\n", len);
        for (j = i - 1; j>0; --j)
            swapChar(&str[j], &str[j - 1]);
        ++len;
        //printf("After rearranging first word:");
        //printf("%s\n", str);
        //printf("Pushing first word toward the end\n");
        for (; k + 2 * len <= length; k = k + len) {
            for (int l = k; l<k + len; ++l) {
                swapChar(&str[l], &str[l + len]);
            }
            //printf("---%s---\n", str);
        }
        //printf("As blocks:");
        //printf("%s\n", str);
        //printf("K VALUE: %d\n", k);
        for (; k + len<length; ++k) {
            for (n = k + len; n>k; --n) {
                //printf("N VALUE: %d\n", n);
                swapChar(&str[n], &str[n - 1]);
            }
        }
        //printf("One by one:");
        //printf("%s\n", str);
        return len;
    }

    void str_words_in_rev1(char *input, int length){
    int len = 0;
    for (int end = length; end>0; end = end - len) {
        //printf("End:%d\n", end);
        len = pushToEnd(input, end);
    }
}

一旦您理解了问题陈述和我已实施的解决方案,以下是我的问题:

我的解决方案的时间复杂度是多少?我认为第一个解决方案具有O(n)复杂度,第二个解决方案可能是O(n ^ 2),但我不确定。

两种解决方案均不考虑不对称间距。单词是相反的,间距也是相反的。在存在对称间距/多对称间距的情况下,它是不可察觉的。问题陈述在这方面尚不清楚,但我希望你对是否应该考虑它的看法。

1 个答案:

答案 0 :(得分:0)

Solution1 O(N)时间复杂度。 as,
Solution2是 O(kN),其中k是字符串中单词的数量,在最坏的情况下,所有单词都是单个字符 O(N ^ 2)。并且你正在逐字逐句地移动并将其他单词交换到前面,所以它是 O(kN)。