[英]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 + 1
到end_anchor
所有字符。 + 1
是因為實現: start_ptr
指向空白字符,打印例程將打印從i
到n
所有字符。 一旦我們檢測到一個空白區域,我們將其打印出來並跳過相鄰的空白區域(在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.