如何在C中逐字翻译句子?

时间:2012-03-09 07:58:11

标签: c string performance algorithm cstring

#include <stdio.h>

int main(void)
{
  int i,j;
  int wordstart = -1;
  int wordend = -1;
  char words[]= "this is a test";
  char temp;

  // Reverse each word
  for (i = 0; i < strlen(words); ++i)
  {
    wordstart = -1;
    wordend = -1;
    if(words[i] != ' ') 
      wordstart = i;
    for (j = wordstart; j < strlen(words); ++j)
    {
      if(words[j] == ' ')
      {
        wordend = j - 1;
        break;
      }
    }
    if(wordend == -1)
      wordend = strlen(words);
    for (j = wordstart ; j <= (wordend - wordstart) / 2; ++j)
    {
      temp = words[j];
      words[j] = words[wordend - (j - wordstart)];
      words[wordend - (j - wordstart)] = temp;
    }
    i = wordend;
    printf("reversed string is %s:", words);
  }
}

我试过这种方式,但我得到了这个输出:
siht is a test
我的预期输出是:
test a is this

如果有人采用不同的方法来解决时间复杂度非常低或者纠正我,如果这是正确的方法,我将不胜感激。感谢

12 个答案:

答案 0 :(得分:1)

您可以创建双链表作为基础数据结构。然后,迭代单词并在找到它们时将它们插入列表中。

当你到达句子的末尾时,只需向后遍历列表并在浏览时打印单词

答案 1 :(得分:1)

也许这属于代码审查网站?

你的方法对我来说似乎非常有效(除了我只调用strlen(单词)一次并将结果保存在寄存器中)。

两个可能的错误如下:

wordend = strlen(words);

应该是

wordend = strlen(words)-1;

for(j = wordstart ; j <= (wordend - wordstart) / 2 ; ++j) {

应该是

for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {

最终代码看起来像(有一些额外的{}):

    #include <stdio.h>
    int main(int argc,char *argv[])
    {
        int i,j;
        char words[]= "this is a test";
        int L=strlen(words);

        // Reverse each word
        for(i = 0; i < L; ++i) {
          int wordstart = -1;
          int wordend = -1;
          if(words[i] != ' ') 
          {
            wordstart = i;

            for(j = wordstart; j < L; ++j) {
              if(words[j] == ' ') {
                wordend = j - 1;
                break;
              }
            }
            if(wordend == -1)
              wordend = L-1;
            for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {
              char temp = words[j];
              words[j] = words[wordend - (j - wordstart)];
              words[wordend - (j - wordstart)] = temp;
            }
            i = wordend;
          }
        }
        printf("reversed string is %s:",words);
        return 0;   
    }

答案 2 :(得分:1)

我们只需使用适合我们需求的n * 1 2D角色阵列即可!

#include <stdlib.h>

int main()
{
    char s[20][20];
    int i=0, length=-1;
    for(i=0;;i++)
    {
        scanf("%s",s[i]);
        length++;
        if(getchar()=='\n')
            break;
    }
    for(i=length;i>=0;i--)
        printf("%s ",s[i]);
    return 0;
}

答案 3 :(得分:0)

开始标记最后一个字符的行并继续第一个字符。保持一个指针锚定在当前单词的基础上,另一个指针指向,当找不到单词start时将减少。当你在这样的扫描中发现一个单词开始时,从单词开始指针打印到单词结束锚点。将单词end anchor更新为当前单词start char的前一个字符。

您可能希望在扫描时跳过空格字符。

<强>更新

这是一个快速实施:

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

#define MAX_BUF 256

void show_string (char *str, int i, int n)
{
  while (i <= n)
  {
    printf ("%c", str[i]);
    i++;
  }
}

int main (void)
{
  char str[MAX_BUF];
  int end_anchor, start_ptr;
  int state;

  printf ("\nEnter a string: ");
  scanf (" %[^\n]", str);

  start_ptr = strlen (str) - 1;

  end_anchor = start_ptr;
  state = 0;
  while (start_ptr >= -1)
  {
    switch (state)
    {
      case 0:
             if ((!isspace (str[start_ptr]) && (start_ptr >= 0)))
             {
               start_ptr--;
             }
             else
             {
               state = 1;
             }
             break;

      case 1:
             show_string (str, start_ptr + 1, end_anchor);
             state = 2;
             start_ptr--;
             printf (" ");
             break;

      case 2:
             if (!isspace (str[start_ptr]))
             {
               state = 0;
               end_anchor = start_ptr;
             }
             else
             {
               start_ptr--;
             }
             break;
    }
  }


  printf ("\n");
  return 0;
}

end_anchor指向每个结尾的单词,start_ptr找到end_anchor结尾的单词的开头。当我们找到单词start(通过空白字符或start_ptr = -1)时,我们会打印从start_ptr + 1end_anchor的所有字符。 + 1是因为实现:start_ptr指向空白字符,打印例程将打印从in的所有字符。一旦我们检测到一个空白区域,我们就会打印它,然后我们跳过相邻的空白空间(在case 2中),只保留一个手动打印的空白区域。一旦检测到非空白空间,我们就会有另一个单词结束,为此我们在end_anchor中将case 2设置为此索引,并设置state = 0,以便我们可以搜索这个词再次开始。

答案 4 :(得分:0)

我会使用与strrchr类似的写函数来查找' '的最后一次出现,如果找到后面的印刷字,请用' '重写此'\0'并重复它在循环中直到找不到更多的单词。最后,我会再次打印此字符串的内容,因为在第一个单词之前很可能没有' '

我会编写自己的函数而不是strrchr因为strrchr计算给定字符串的长度,在这种情况下这是多余的。此长度不必多次计算。

以下是代码:

char* findLastWord(char* str, int* len)
{
    int i;
    for (i = *len - 1; i >= 0; --i)
    {
        if (str[i] == ' ')
        {
            str[i] = '\0';
            if (i < *len - 1)
            {
                *len = i - 1;
                return &str[i + 1];
            }
        }
    }
    return NULL;
}

int main (int argc, char *argv[])
{
    char str[] = " one two three  four five six ";
    int len = strlen(str);

    char* lastWord = findLastWord(str, &len);
    while (lastWord != NULL)
    {
        printf("%s\n", lastWord);
        lastWord = findLastWord(str, &len);
    }
    if (len > 1)
        printf("%s\n", str);
    return 0;
}

输出:

six
five
four
three
two
one

希望这会有所帮助;)

答案 5 :(得分:0)

if(words[i] != ' ') 
    wordstart = i;

这句话怎么样呢?如果单词[i] =='',则wordstart保持为-1。 所以也许尝试使用:

while (words[i] && words[i] == ' ') ++i;
  if (!words[i])
      break;
wordstart = i;

然后你应该从i循环中输出结果。 最后,如果你想得到你期望的结果,你应该再次用你在循环中使用的方式反转整个句子。

答案 6 :(得分:0)

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

void reverse(char *str, size_t len)
{
    char tmp;
    size_t beg, end;
    if (len <=1) return;

    for (beg=0,end=len; beg < --end ; beg++) {
        tmp = str[beg];
        str[beg] = str[end];
        str[end] = tmp;
    }
}

int main(void)
{
    char sentence[] = "one two three four five";
    size_t pos, len;

    printf("Before:%s\n",sentence);
    for (pos = len= 0;  sentence[pos]; pos += len) {
        pos += strspn( sentence+pos, " \t\n" );
        len = strcspn( sentence+pos, " \t\n" );
        reverse ( sentence + pos, len );
        }
    reverse ( sentence , pos );

    printf("After:%s\n",sentence);

    return 0;
}

答案 7 :(得分:0)

 #include <iostream>
 #include <string>   
  using namespace std;
  char* stringrev(char s[], int len)
  {
    char *s1 = (char*)malloc(len+1);
    int i=0;
    while (len>0)
    {
      s1[i++] = s[--len];
    }
   s1[i++] = '\0';
    return s1;   
  }

   void sentrev(char s[], int len)
 {
    int i=0; int j=0;
     char *r = (char*)malloc(len+1);
     while(1)
     {
     if(s[j] == ' ' || s[j] == '\0')
     {
       r = stringrev(s+i, j-i);
       i = j+1;
       cout<<r<<" ";
     }
    if (s[j] == '\0')
    break;
    j++;
   }

 }


int main()
{
char *s = "this is a test";
char *r = NULL;
int len = strlen(s);
cout<<len<<endl;
r = stringrev(s, len);
cout<<r<<endl;
sentrev(r, len);
return 0;
}

上面的代码使用char * r快速反转句子  和打印cout&lt;

答案 8 :(得分:0)

#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char st[50], rst[50];
printf("Enter the sentence...\n");
gets(st);
int len=strlen(st), p;
int j=-1,k;
p=len;
for(int i=(len-1); i>=0; i--)
{
    //searching for space or beginning
    if(st[i]==' ')
    {
        //reversing and storing each word except the first word
        for(k=i+1;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
        j++;
        rst[j]=' ';
        printf("\n");
        p=i;
    }
    else if(i==0)
    {
        //for first word
        for(k=i;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
    }

}
printf("Now reversing the sentence...\n");
puts(rst);
return 0;
}

答案 9 :(得分:0)

使用main for循环遍历到句子结尾: 复制字符串中的字母,直到找到空格。 现在调用add@beginning函数并在该函数中每次将字符串传递给链表时添加字符串。 打印链接列表的内容,中间有一个空格以获得预期的输出

答案 10 :(得分:0)

我的代码,只是从最后一个遍历,如果你发现空格打印前面的字符,现在将结束更改为空格-1;这将打印到第二个单词,最后只用一个打印第一个单词loop.Comment for alter approach。

程序:

#include<stdio.h>
int main()
{
 char str[200];
int i,j,k;
scanf("%[^\n]s",&str);
for(i=0;str[i]!='\0';i++);
i=i-1;
for(j=i;j>=0;j--)
{
    if((str[j])==' ')
    {
        for(k=j+1;k<=i;k++)
        {
            printf("%c",str[k]);
        }
        i=j-1;
        printf(" ");
    }

}
for(k=0;k<=i;k++)
{
    printf("%c",str[k]);
}
}

答案 11 :(得分:0)

using stack 

#include <iostream>  
#include <stdio.h>
#include <stack>

int main()
{ 

    std::stack<string> st;
    char *words= "this is a test";
    char * temp =   (char *)calloc(1, sizeof(*temp));
    int size1= strlen(words);
    int k2=0;
    int k3=0;
    for(int i=0;i<=size1;i++)
    {
       temp[k2] = words[i];
       k2++;
        if(words[i] == ' ')     
        {  
            k3++;
            if(k3==1)
                temp[k2-1]='\0';

            temp[k2]='\0';
            st.push(temp);
            k2=0;           
        }
        if(words[i] == '\0')
        {
            temp[k2]='\0';
            st.push(temp);
            k2=0;
            break;
        }               
    }

  while (!st.empty())
  {
       printf("%s",st.top().c_str());
        st.pop();
  }