#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
如果有人采用不同的方法来解决时间复杂度非常低或者纠正我,如果这是正确的方法,我将不胜感激。感谢
答案 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 + 1
到end_anchor
的所有字符。 + 1
是因为实现:start_ptr
指向空白字符,打印例程将打印从i
到n
的所有字符。一旦我们检测到一个空白区域,我们就会打印它,然后我们跳过相邻的空白空间(在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();
}