[英]Sorting words in alphabetically order C
所以我的練習是對一維字符數組中的單詞進行排序。 我的代碼幾乎可以工作,但它總是跳過最后一個字的最后一個字符。 這是我的代碼。 我添加了一些注釋以使其具有某種可讀性。 我知道這不是很棒的代碼,但我才剛剛開始編程。
int main(void) {
char input[] = "If you are working on something that you really care about you dont have to be pushed The vision pulls you Steve Jobs";
sort_alphabetically(input);
printf("%s", input);
}
int sort_alphabetically(char tab[]) {
int j = 0, k = 0, i = 0, g = 0, f = 0, l = 0;
char tmp[1001];
char tmp2[501][1001];
while (tab[i] == ' ') // skipping leading whitespaces
i++;
for (j = i; tab[j] != '\0'; j++) {
if (tab[j] != ' ' && tab[j + 1] != '\0')
k++; // counting word length
else if (tab[j] == ' ' || tab[j + 1] == '\0' || tab[j + 1] == '\0') {
// copying word t0 2d array
for (g = k; g > 0; g--) {
tmp[l] = tab[j - g];
l++;
}
tmp[l] = 0;
strcpy(tmp2[f], tmp); // copying
f++; //words ++ in tmp2
k = 0;
l = 0;
tmp[0] = 0;
}
}
tab[0] = 0;
tmp[0] = 0;
for (j = 0; j < f; j++) {
for (i = 0; i < f - 1; i++) {
if (strcmp(tmp2[i], tmp2[i + 1]) > 0) { //sorting words in alphabeticall order
strcpy(tmp, tmp2[i]);
strcpy(tmp2[i], tmp2[i + 1]);
strcpy(tmp2[i + 1], tmp);
}
}
}
for (i = 0; i < f; i++) {
strcat(tab, tmp2[i]); // copying to tab
strcat(tab, " "); //adding spaces after each word
}
// removing whitespaces
for (i = 0; tab[i] == ' ' || tab[i] == '\t'; i++);
for (j = 0; tab[i]; i++) {
tab[j++] = tab[i];
}
tab[j] = '\0';
}
;
運行此代碼后,它會在最后一個單詞 (Jobs) 中刪除s
。 如果有人能幫我做這道意大利面,我會很高興。
問題在於您如何處理空字節與空間。 在空格的情況下,當您復制字符串時,您實際上是在空格上。 但是在空字節的情況下,您是空字節之前的一個。 這會導致一對一錯誤。 您需要修改代碼以避免對空格和空字節進行不同的處理:
for (j = i; tab[j] != '\0'; j++) {
//In the space case, you are on the space, but in the \0 case
//you were one before it.
//Changed this if statement so that you always copy the string
//when you're at the last character.
if (tab[j + 1] == ' ' || tab[j + 1] == '\0') {
//k is a length, but we're using it as an index
//so we will need to adjust by one
for (g = k; g > 0; g--) {
tmp[l] = tab[j - g + 1];
l++;
}
}
else
{
k++;
}
}
我通過放置打印語句來解決這個問題,這些語句顯示了每個周期的tab[j]
的值和k
的值。 使用打印語句或調試器觀察程序執行通常是診斷此類問題的最佳方法。
您遇到的問題是當您到達輸入( tab
)字符串的末尾時將字符復制到tmp
緩沖區; 也就是說,當tab[j + 1] == '\\0'
為真時。 在這種情況下,您不會復制此for
循環中的最后一個數據:
for (g = k; g > 0; g--) {
tmp[l] = tab[j - g];
l++;
}
要解決此問題,只需更改循環的“條件”以包含g
為零時的內容,並在遇到空格字符時跳過此“迭代”:
for (g = k; g >= 0; g--) { // Make sure to include any 'last' character
if (tab[j - g] != ' ') { // ... but skip if this is a space
tmp[l] = tab[j - g];
l++;
}
}
另請注意,您在此行中有一個冗余測試:
else if (tab[j] == ' ' || tab[j + 1] == '\0' || tab[j + 1] == '\0') {
沒有第三個測試(與第二個測試相同)也可以編寫,因此:
else if (tab[j] == ' ' || tab[j + 1] == '\0') {
警告:大多數其他響應者都指出了您代碼中的主要錯誤,但這有一些較小的錯誤和一些簡化。
在執行strcat
返回tab
之前,我們應該執行tab[0] = 0
以便初始strcat
正常工作。
在復制單詞的那個之后執行strcat(tab," ")
超出tab
的末尾,因此是未定義的行為。 它還需要一個不必要的清理循環來刪除一開始不應該存在的額外空間。
最初的“拆分成單詞”循環可以[大大]簡化。
冒泡排序有一些標准的加速
我意識到您才剛剛開始 [有些學校實際上提倡i
、 j
等],但最好使用一些 [更多] 描述性名稱
無論如何,這是一個稍微重構的版本:
#include <stdio.h>
#include <string.h>
int opt_dbg;
#define dbg(_fmt...) \
if (opt_dbg) \
printf(_fmt)
void
sort_alphabetically(char tab[])
{
char tmp[1001];
char words[501][1001];
char *src;
char *dst;
char *beg;
int chr;
int wordidx;
int wordcnt;
wordidx = 0;
dst = words[wordidx];
beg = dst;
// split up string into individual words
src = tab;
for (chr = *src++; chr != 0; chr = *src++) {
switch (chr) {
case ' ':
case '\t':
// wait until we've seen a non-white char before we start a new
// word
if (dst <= beg)
break;
// finish prior word
*dst = 0;
// point to start of next word
dst = words[++wordidx];
beg = dst;
break;
default:
*dst++ = chr;
break;
}
}
// finish last word
*dst = 0;
// get number of words
wordcnt = wordidx + 1;
if (opt_dbg) {
for (wordidx = 0; wordidx < wordcnt; ++wordidx)
dbg("SPLIT: '%s'\n",words[wordidx]);
}
// in bubble sort, after a given pass, the _last_ element is guaranteed to
// be the largest, so we don't need to examine it again
for (int passlim = wordcnt - 1; passlim >= 1; --passlim) {
int swapflg = 0;
// sorting words in alphabetical order
for (wordidx = 0; wordidx < passlim; ++wordidx) {
char *lhs = words[wordidx];
char *rhs = words[wordidx + 1];
if (strcmp(lhs,rhs) > 0) {
dbg("SWAP/%d: '%s' '%s'\n",passlim,lhs,rhs);
strcpy(tmp,lhs);
strcpy(lhs,rhs);
strcpy(rhs,tmp);
swapflg = 1;
}
}
// if nothing got swapped, we can stop early (i.e. everything is in
// sort)
if (! swapflg)
break;
}
// clear out destination so [first] strcat will work
tab[0] = 0;
// copy back words into original string
// adding the space as a _prefix_ before a word eliminates the need for a
// cleanup to remove the last space
for (wordidx = 0; wordidx < wordcnt; ++wordidx) {
dbg("SORTED: '%s'\n",words[wordidx]);
// adding spaces before each word
if (wordidx > 0)
strcat(tab, " ");
// copying to tab
strcat(tab,words[wordidx]);
}
}
int
main(int argc,char **argv)
{
char input[] = "If you are working on something that you really care"
" about you dont have to be pushed The vision pulls you Steve Jobs";
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'd':
opt_dbg = ! opt_dbg;
break;
}
}
sort_alphabetically(input);
printf("%s\n", input);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.