簡體   English   中英

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

[英]how to perform reversing a sentence Word by Word in C?

#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

如果有人采用不同的方法,時間復雜度非常低,或者如果這是正確的方法,那么我會很感激。 謝謝

我們只需使用適合我們需求的* 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;
}

您可以創建雙鏈表作為基礎數據結構。 然后,迭代單詞並在找到它們時將它們插入列表中。

當您到達句子的末尾時,只需向后遍歷列表並在您瀏覽時打印單詞

也許這屬於代碼審查網站而不是?

你的方法對我來說似乎非常有效(除了我只調用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;   
    }
 #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 <來快速反轉句子

#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;
}

使用main for循環遍歷到句子的結尾:復制字符串中的字母,直到找到空格。 現在調用add@beginning函數,並在每次將字符串傳遞給鏈表時添加字符串。 打印鏈表的內容,其間有空格以獲得預期的輸出

我的代碼,只是從最后一個遍歷,如果你發現空格打印前面的字符,現在將結束更改為空格-1;這將打印到第二個單詞,最后只使用單個for循環打印第一個單詞。改變方法。

程序:

#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]);
}
}
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();
  }

開始標記最后一個字符的行並繼續第一個字符。 保持一個指針錨定在當前單詞的基礎上,另一個指針指向,當找不到單詞start時將減少。 當你在這樣的掃描中發現一個單詞開始時,從單詞開始指針打印到單詞結束錨點。 將單詞結束錨更新為當前單詞start char的前一個字符。

您可能希望在掃描時跳過空白字符。

UPDATE

這是一個快速實現:

#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持有結尾的單詞的end_anchor 當我們找到一個單詞start(通過blankspace字符或start_ptr = -1)時,我們打印從start_ptr + 1end_anchor所有字符。 + 1是因為實現: start_ptr指向空白字符,打印例程將打印從in所有字符。 一旦我們檢測到一個空白區域,我們將其打印出來並跳過相鄰的空白區域(在case 2 ),並且只保留一個手動打印的空白區域。 一旦檢測到非空白空間,我們就會得到另一個單詞結束,為此我們將end_anchor設置為case 2中的該索引,並設置state = 0 ,以便我們可以再次搜索單詞start。

我會使用類似於strrchr的寫函數來查找' '最后一次出現,如果找到后面的打印字,用'\\0'重寫這個' ' '\\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

希望這可以幫助 ;)

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

這個說法怎么樣呢? 如果單詞[i] =='',則wordstart保持為-1。 所以也許嘗試使用:

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

然后你應該從i循環中輸出結果。 最后,如果你想得到你期望的結果,你應該再次用你在循環中使用的方式反轉整個句子。

#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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM