輸入10個字串,印出共有多少不同的子句?

Home Home
引用 | 編輯 karen7710
2007-06-09 18:51
樓主
推文 x0
請問大大以下這個題目應該怎麼寫呢?
題目:
輸入10個字串,每個字串 ..

訪客只能看到部份內容,免費 加入會員



獻花 x0
引用 | 編輯 GNUGCC
2007-06-09 22:47
1樓
  
可能的做法是先配置一塊二維陣列儲存找到的字串
當然最好是可以用動態配置記憶體的方式比較省記憶體
然後再根據找到的字串先記錄在二維陣列可以用在
之後找到相同的字串的時候記錄出現字串的次數...

這個是我目前想到的...妳可以先試著寫看看...^^

獻花 x0
引用 | 編輯 a86980
2007-06-10 11:11
2樓
  
這個題目有一點排列組合的味道

所以要套用到排列組合的公式

.
.
.
.
.
.
.

排列組合的方式

偶忘光了 表情

獻花 x0
引用 | 編輯 karen7710
2007-06-10 15:36
3樓
  
我只會設輸入10個字串,跟字串長度的限制,

印出有多少不同的子句不知道要怎麼寫?

下面是輸入10個字串跟長度限制的程式,
複製程式
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void)
{
    char a[10][49];
    int i; 
    printf("輸入十個字串\n"); 
      for(i=0;i<10;i++)
       {
           gets(a[i]); 
       }
     system("pause");
     return 0;   
}


獻花 x0
引用 | 編輯 ladese05
2007-06-10 20:02
4樓
  
表情 表情 表情
已經存到ARRAY了
直接比對他們就OK拉
用個COUNTER計算有幾個不同
如果不知道怎麼下手
你先從比對2個字串開始寫
2個字串會了
10個自然迎刃而解

獻花 x0
引用 | 編輯 gamewalk
2007-06-11 05:47
5樓
  
我的想法是前面應該就先把輸入的字串存起來,在來應該就會用到strtok(切割字串)跟strcmp(比對字串,但是有分大小寫)...

最後我的作法可能對不懂指標的人有點難,就是先建立一個結構裡面就放 子句,次數和一個指著與自己相同結構的指標, 以LinkList的形式來做新增....不過如果不懂指標 還是不建議你用....可以參考其他大大的寫法...

獻花 x0
引用 | 編輯 karen7710
2007-06-11 19:40
6樓
  
因為一個字串裡,會有好幾個子句,
那就不能直接二個字串比較,要先把自己字串裡的子句先比較!
那用strcmp(a,??),問號那裡要打什麼跟a比較呢?

獻花 x0
引用 | 編輯 GNUGCC
2007-06-11 23:13
7樓
  
如果輸入一個字串然後用空白字元做間隔當做下一個字串的開始
可能必需先用迴圈找出每個陣列儲存的字串中那些地方有空白字元並且
做比對動作應該可以解決這個問題...

獻花 x0
引用 | 編輯 gamewalk
2007-06-12 00:40
8樓
  
你也可以把切割出來的子句再找個地方放 , 這種新增動作是用動態配制比較好...但是如果不會的話那就宣告一個存放子句的陣列以及一個計數的陣列至於多大自己設吧... , 然後比對如果比對完沒有相同的就新增一個需要比對的子句並且在他的計數欄設為 1 (因為第一個自己要算 ),若有相同的就只要在他計數欄+1即可....

獻花 x0
引用 | 編輯 GNUGCC
2007-06-12 00:58
9樓
  
這個範例會用到幾個函式庫,例如像 strcpy(), strchr(), strcmp() 或是 strcmpi()...
我建議妳可以先查詢這些函式庫的使用方式及參數型態
並試著寫看看然後 po 出來有問題的地方比較好給答案...

獻花 x0
引用 | 編輯 karen7710
2007-06-12 21:05
10樓
  
不好意思,我真的想不出來要怎麼比較>"< 表情
我目前有教到strcpy(), strcmp()可是不太會運用!
麻煩大大可以提示一下大概要怎麼打~ 謝謝囉^^

獻花 x0
引用 | 編輯 GNUGCC
2007-06-13 01:24
11樓
  
// 儲存輸入的字串
char string_save[10][50];
// 儲存 string_save 找到的字串
char find_string[100][50];
// 記錄字串出現的筆數
int find_count[100];

void FindCompare(void)
{
  int i, j, k, v;
  for ( i = 0, v = 0; i < 10; i++ )
  {
    for ( j = 0, k = strlen(string_save)); j <= k; j++ )
      if ( string_save[j]) == 32 || j == k )
      {
        string_save[j] = 0;
        for ( int f = 0; f < 100; f++ )
          if ( strlen(find_string[f])) == 0 )
          {
            strcpy(find_string[f], string_save + v);
      find_count[f]++;
      break;
          }
          else if ( strcmpi(find_string[f], string_save + v) == 0 )
          {
            find_count[f]++;
      break;
          }      

          v = j + 1;
      }

      v = 0;
  }
}

上面的函式只負責從 string_save 陣列中找出字串重復
的次數, 要記得在妳寫的主程式內將輸入的字串存在
string_save 陣列內, 輸入的字串大小不要超過 49 個字元,
假如要輸入的字串會很大的話請自行調整陣列大小...
如果程式看不懂的話再拿出來討論吧... 祝妳成功^^

如果程式寫的不好的話請多多包含...歡迎指教^^

獻花 x0
引用 | 編輯 GNUGCC
2007-06-13 01:32
12樓
  
因為 po 上去的時候發現有些字沒有在裡面所以做了更新 :

// 儲存輸入的字串
char string_save[10][50];
// 儲存 string_save 找到的字串
char find_string[100][50];
// 記錄字串出現的筆數
int find_count[100];

void FindCompare(void)
{
int i, j, k, v;
for ( i = 0, v = 0; i < 10; i++ )
{
  for ( j = 0, k = strlen(string_save[ i ]); j <= k; j++ )
    if ( string_save[ i ][ j ] ) == 32 || j == k )
    {
    string_save[j] = 0;
    for ( int f = 0; f < 100; f++ )
      if ( strlen(find_string[ f ]) == 0 )
      {
        strcpy(find_string[ f ], string_save[ i ] + v);
    find_count[f]++;
    break;
      }
      else if ( strcmp(find_string[ f ], string_save[ i ] + v) == 0 )
      {
        find_count[f]++;
    break;
      }    

      v = j + 1;
    }

    v = 0;
}
}

獻花 x1
引用 | 編輯 gamewalk
2007-06-13 05:07
13樓
  
樓上的GNUGCC大大...雖然你改了但是還是有一個地方被系統吃掉了....提醒你一下 希望別介意 表情
if ( string_save[ i ][ j ] ) == 32 || j == k )
{
string_save[j] = 0; <-----這裡 應該是 string_save[ i ][ j ] 我想那個 [ i ] 又被吃掉了 我之前也遇過
for ( int f = 0; f < 100; f++ )
if ( strlen(find_string[ f ]) == 0 )
{
strcpy(find_string[ f ], string_save[ i ] + v);
find_count[f]++;
break;
}
else if ( strcmp(find_string[ f ], string_save[ i ] + v) == 0 )
{
find_count[f]++;
break;
}
v = j + 1;
}

其實GNUGCC大大的方法就可以了....不過看起來好像有點複雜 表情 ...如果邏輯不好的人可能很快就掛了... 像我就快掛了 表情

獻花 x0
引用 | 編輯 GNUGCC
2007-06-13 07:34
14樓
  
呵呵^^昨天看了很久還是有漏網之魚啊...感謝 gamewalk 大大的指教...感激不盡
在下的程式功力淺薄歡迎網上大大能提供更好的演算法解決這個問題...^^

獻花 x0
引用 | 編輯 gamewalk
2007-06-13 17:43
15樓
  
下面是引用GNUGCC於2007-06-13 07:34發表的 :
呵呵^^昨天看了很久還是有漏網之魚啊...感謝 gamewalk 大大的指教...感激不盡
在下的程式功力淺薄歡迎網上大大能提供更好的演算法解決這個問題...^^


其實只是我覺得一般這樣使用的話會很容易自亂陣腳...但是GNUGCC大大卻能運用自如... 表情

也許多加一些註解看起來就不會那麼複雜了...不過樓主看得懂的話...那就不用了...
因為這又不是為我寫得 表情

P.S.還有就是貼程式碼用"插入代碼"這個功能 , 應該就不會發生那種 [ i ] 被吃掉的問題了...
(雖然這麼說但是我也常常忘記用)

獻花 x0
引用 | 編輯 karen7710
2007-06-13 21:32
16樓
  
我加上我之前輸入10個字串的程式後,好像出現錯誤不能跑,麻煩大大看看哪裡出錯!
複製程式
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void FindCompare(void);

int main(void)
{
char string_save[10][50];
char find_string[100][50];
int a,find_count[100];
 
    printf("輸入十個字串\n"); 
      for(a=0;a<10;a++)
       {
           gets(string_save[a]); 
       }
     FindCompare();
     system("pause");
     return 0;   
}


void FindCompare(void)
{
char string_save[10][50];
char find_string[100][50];
int find_count[100];     
int i, j, k, v;
for ( i = 0, v = 0; i < 10; i++ )
{
  for ( j = 0, k = strlen(string_save[ i ]); j <= k; j++ )
    if ( string_save[ i ][ j ] ) == 32 || j == k )
    {
    string_save[i][j] = 0;
    for ( int f = 0; f < 100; f++ )
      if ( strlen(find_string[ f ]) == 0 )
      {
        strcpy(find_string[ f ], string_save[ i ] + v);
    find_count[f]++;
    break;
      }
      else if ( strcmp(find_string[ f ], string_save[ i ] + v) == 0 )
      {
        find_count[f]++;
    break;
      }     

      v = j + 1;
    }

    v = 0;
}
} 


獻花 x0
引用 | 編輯 GNUGCC
2007-06-13 22:13
17樓
  
char string_save[10][50];
char find_string[100][50];
int find_count[100];  

把上面的陣列放在函式外面,包括主程式和 FindCompare 函式都不要有陣列的宣告...
呼叫完 FindCompare 函式記得要在加上輸出的程式列出搜尋結果...
或許可以先把陣列內的變數值先設為 0 確保資料不會有問題^^

在做測試的時候記得字串跟下一個字串要用空白隔開因為程式裡有用到是否遇到空白字元 :

if ( string_save[ i ][ j ] ) == 32 || j == k )

代碼 32 代表的是空白字元, 先這樣試看看...^^

獻花 x0
引用 | 編輯 gamewalk
2007-06-13 22:41
18樓
  
好像又看到一個問題 表情
if ( string_save[ i ][ j ] ) == 32 || j == k ) <--裡面string_save[ i ][ j ]前面 好像少了一個左括號" ( "

獻花 x0
引用 | 編輯 GNUGCC
2007-06-13 23:11
19樓
  
的確...再次感恩 gamewalk 大大...
下面才是正確的...

if ( (string_save[ i ][ j ]) == 32 || j == k )

今天怎麼搞的 ??? 連我自已也不知道...

獻花 x0
引用 | 編輯 karen7710
2007-06-14 08:09
20樓
  
更改過後的程式,還是有錯誤~
出現這個錯誤:
  In function `FindCompare':
35 'for' loop initial declaration used outside C99 mode
複製程式
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void FindCompare(void);
char string_save[10][50];
char find_string[100][50];
int find_count[100];  

int main(void)
{

int a;
 
    printf("輸入十個字串\n"); 
      for(a=0;a<10;a++)
       {
           gets(string_save[a]); 
       }
     FindCompare();
     system("pause");
     return 0;   
}


void FindCompare(void)
{
   
int i, j, k, v;
for ( i = 0, v = 0; i < 10; i++ )
{
  for ( j = 0, k = strlen(string_save[ i ]); j <= k; j++ )
    if ( (string_save[ i ][ j ] ) == 32 || j == k )
    {
    string_save[i][j] = 0;
    for ( int f = 0; f < 100; f++ )
      if ( strlen(find_string[ f ]) == 0 )
      {
        strcpy(find_string[ f ], string_save[ i ] + v);
    find_count[f]++;
    break;
      }
      else if ( strcmp(find_string[ f ], string_save[ i ] + v) == 0 )
      {
        find_count[f]++;
    break;
      }     

      v = j + 1;
    }

    v = 0;
}
} 


獻花 x0
引用 | 編輯 gamewalk
2007-06-14 15:54
21樓
  
請問你是要用 c 還是 c++ 如果副檔名是.cpp的話應該是正常 , 若是.c的話把FimdCompare 裡面的
for (int f = 0; f < 100; f++ ) 裡面的 int f 改成 宣告在前面變數那邊...,也就是這裡會變成
for( f= 0; f < 100; f++ )

獻花 x1
引用 | 編輯 karen7710
2007-06-14 18:47
22樓
  
原來如此,謝謝囉!
那要印出來的話printf裡面應該打什麼呢?

獻花 x0
引用 | 編輯 gamewalk
2007-06-14 19:14
23樓
  
複製程式
  for( a = 0 ; a < 100 ; a++ )
  {
       if( find_string[a][0] == 0 ) //當find_string[a]是空的,表示是最後一個...就break跳出 
           break;
       else
           printf("%s : %d次\n",find_string[a],find_count[a]);
  }

要印的話...應該就這樣吧

獻花 x0
引用 | 編輯 karen7710
2007-06-14 19:31
24樓
  
嗯嗯,感謝你的回答喔^^ 表情

獻花 x0