[2013年2月26日]
1. 編程判斷兩棵給定的二叉樹是否相等
Version 1 [Accepted 2013/02/27]
bool equal_bin_tree(struct binary_tree* b_tree1, struct binary_tree* b_tree2)
{
if(b_tree1 == NULL)
{
if(b_tree2 == NULL) return true;
else return false;
}
else
{
if((b_tree2 == NULL)) return false;
else
{
if(b_tree1->data != b_tree2->data) return false;
else
{
equal_bin_tree(b_tree1->left, b_tree2->left);
equal_bin_tree(b_tree1->right, b_tree2->right);
}
}
}
}
Version 2
bool equal_bin_tree(struct binary_tree* b_tree1, struct binary_tree* b_tree2)
{
bool ans = false;
if((b_tree1 == NULL) && (b_tree2 == NULL)) return true;
if((b_tree1 != NULL) && (b_tree2 != NULL))
{
if(b_tree1->data == b_tree2->data)
{
ans = equal_bin_tree(b_tree1->left, b_tree2->left);
if(ans) ans = equal_bin_tree(b_tree1->right, b_tree2->right);
}
}
return ans;
}
2. 給定一篇英語文章,提取其中的單詞,並統計各個單詞在文章中出現的次數
Version 1 [Accepted 2013/03/01]
//File name: word_count.h
#ifndef _WORD_COUNT_H_
#define _WORD_COUNT_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
struct word_node{
int num;
char word[MAX_LEN];
struct word_node* next;
};
struct word_node* word_count(char* file_name,struct word_node* head);
void eat_white_space(FILE* fp);
int read_word(FILE* fp, char word[]);
struct word_node* insert_word(struct word_node* head, char word[]);
void print(struct word_node* head);
struct word_node* create_new_node(char word[]);
void free_link(struct word_node* head);
#endif
// File name: word_count.cpp
#include "word_count.h"
struct word_node* word_count(char* file_name,struct word_node* head)
{
char word[MAX_LEN] = {0};
FILE* fp = NULL;
struct word_node* new_node = NULL;
head->next = NULL;
if((fp = fopen(file_name, "r")) == NULL)
{
printf("can not open the file \"%s\".\n", file_name);
exit(-1);
} //打開文件
eat_white_space(fp); //消除空白
while(!feof(fp))
{
read_word(fp, word); //讀取單詞
head = insert_word(head, word); //插入鏈表
eat_white_space(fp); //消除空白
}
fclose(fp);
return head;
}
void eat_white_space(FILE* fp)
{
char ch = ' ';
if (fp == NULL) exit(0);
if(!feof(fp))
{
ch = fgetc(fp);
while(1)
{
if((((ch >='A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= '0') && (ch <= '9'))))
{
fseek(fp, -1L, SEEK_CUR);
break; //讀取到的字符爲字母或數字, 則eat結束,文件指針後退一位
}
else
{
if(!feof(fp)) ch = fgetc(fp); //讀取到的字符爲不爲字母和數字, 且文件沒有到達尾部,則繼續讀取下一字符
else break; //讀取到的字符爲不爲字母和數字, 且文件到達尾部,eat結束,
}
}
}
}
int read_word(FILE* fp, char word[])
{
int i = 0;
char ch = '*';
char temp = '*';
if (fp == NULL) exit(0);
while(!feof(fp))
{
ch = fgetc(fp);
if(ch >= 'A' && ch <= 'Z') ch = ch + 32; //若爲大寫字母,則轉換成小寫
if((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) word[i++] = ch; //若爲小寫字母或數字,直接寫入word
else if(ch == '-')
{
if(i != 0)
{
if((temp = fgetc(fp)) == '\n') ; //遇到‘-’, 如果‘-’不在word的第一位,並且‘-’之後緊跟‘\n’,繼續讀取下一字符
else if((word[i - 1] >= 'a' && word[i - 1] <= 'z') || (word[i - 1] >= '0' && word[i - 1] <= '9'))
{
word[i++] = '-';
fseek(fp, -1L, SEEK_CUR);
} // 如果‘-’不在word的第一位,並且‘-’之後緊跟數字或字母,則將‘-’寫入word
}
}
else if(ch == '\'')
{
if(i != 0) word[i++] = '\''; //遇到單引號, 如果不在word的第一位,則寫入word
}
else break;
}
word[i] = '\0'; //讀取word完成後 寫入‘\0’
return 0;
}
struct word_node* insert_word(struct word_node* head, char word[])
{
int len = 0;
int ans = 0;
int flag = 0;
struct word_node* new_node = NULL;
struct word_node* p = NULL;
struct word_node* p_pre = NULL;
len = strlen(word);
if(len > 0)
{
if(head->next == NULL)
{
head->next = create_new_node(word); //head爲空鏈表時,直接插入節點
return head;
}
p_pre = head;
p = head->next;
while(p != NULL) //比較大小,找到新節點的插入位置
{
ans = strcmp(word, p->word);
if(ans < 0) {flag = -1;break;}
else if(ans == 0) {flag = 0;break;}
else
{
p_pre = p;
p = p->next;
flag = 1;
}
}
if(flag == 0) p->num = p->num + 1; //flag = 0,該節點num值加一
else if(flag == -1) //flag = -1,新節點插到該節點之前
{
new_node = create_new_node(word);
p_pre->next = new_node;
new_node->next = p;
}
else //flag = 1,新節點接在該節點之後
{
new_node = create_new_node(word);
p_pre->next = new_node;
}
}
return head;
}
void print(struct word_node* head)
{
int i = 1;
struct word_node* p = NULL;
if(head->next != NULL)
{
p = head->next;
while(p != NULL)
{
printf("%d.%s: %d\n", i++, p->word, p->num);
p = p->next;
}
}
}
struct word_node* create_new_node(char word[])
{
struct word_node* new_node = NULL;
if(strlen(word))
{
new_node = (struct word_node*) malloc(sizeof(word_node));
if(new_node == NULL)
{
printf("Out of memory!\n");
exit(-1);
}
new_node->next = NULL;
new_node->num = 1;
strcpy(new_node->word, word);
return new_node;
}
else return NULL;
}
void free_link(struct word_node* head)
{
struct word_node* p = NULL;
struct word_node* q = NULL;
p = head;
while(p != NULL)
{
q = p->next;
free(p);
p = q;
}
}
// File name: main.cpp
#include "word_count.h"
int main()
{
char file_name[100] = "data.txt";
struct word_node* head = NULL;
printf("Please enter the file name: ");
scanf("%s", file_name); //輸入待統計的文件名
head = create_new_node("head"); //建立一個帶空頭節點的鏈表
head = word_count(file_name,head); //統計單詞
print(head); //打印輸出
free_link(head); //銷燬鏈表
return 0;
}
代碼本身的組織結構和書寫風格都非常漂亮,代碼近250行,達到了預期的鍛鍊與鞏固效果。
編程過程中首次自主使用流程圖來表達自己的設計意圖,在方法和意識上有了質的進步。
這段代碼意義重大,它已經爲你成功開啓了2013年的春天!
Version 2
// File name: main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;
#define ERROR -1
#define MAX_WORD_LEN 50
bool is_part_of_word( char* ch ) { // 判斷是否可能爲一個單詞的組成部分
if( 'a' <= (*ch) && (*ch) <= 'z') return true;
if( 'A' <= (*ch) && (*ch) <= 'Z') {
*ch = 'a' + (*ch) - 'A';
return true;
}
if('0' <= (*ch) && (*ch) <= '9') return true;
if((*ch) == '-') return true;
return false;
}
int main() {
string name;
fstream infile;
map<string, int> record; // 使用c++內置的map數據結構
map<string, int>::iterator iter; // map的迭代結構
cout << "\nPlease input the file name ==> ";
cin >> name;
infile.open(name, ios::in); //以只讀方式打開文件
if( !infile.is_open() ) {
cout << "File : "<<name<<"can not be opened for read ..."<<endl;
return ERROR;
}
while( !infile.eof() ) { // 是否到達文件的末尾
char temp = 'a';
int len = 0;
char c_str[MAX_WORD_LEN + 1] = {'\0'};
temp = infile.get(); // 從文件中讀取一個字符
while(!infile.eof() && is_part_of_word(&temp)) { // 拼接一個單詞
if(len < MAX_WORD_LEN) c_str[len++] = temp; // 防止緩衝區溢出
//infile >> temp;
temp = infile.get();
}
if(len != 0) { // 將一個單詞插入map數據結構
c_str[len] = '\0';
//printf("\n***%s", c_str);
string word(c_str);
iter = record.find(word);
if( iter != record.end() ) {
int counter = iter->second;
iter->second = counter + 1;
} else {
record.insert(pair<string, int>(word, 1));
}
}
}
infile.close();
int num = 0; // 用迭代器遍歷map結構中的內容
for(iter = record.begin(); iter != record.end(); ++ iter) {
cout << ++num << "\t" << iter->first << "\t" << iter->second << endl;
}
return 0;
}
[2013年2月27日]
3. 打印輸出採用冒泡排序算法對下列數據進行排序時的前三趟中間結果。
數據: 7 2 4 9 1 6 8 10 11
[Accepted 2013/03/01]
int bubble_sort(int data[], int length, int n)
{
int i = 0;
int k = 1;
int j = 0;
int temp = 0;
int flag = 0;
if(length <= 0)
{
printf("length should be a positive number!\n");
exit(-1);
}
if(n > length) //若n > length,則 n 取 length 的值
{
printf("The max of n is %d!\n", length);
n = length;
}
for(i = 0; i < n; i++)
{
flag = 0;
for(j = 0; j < (length - 1 - i); j++)
{
if(data[j] > data[j + 1]) //若data[j] > data[j+1],交換兩數的值
{
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
flag = 1;
}
}
print(data, length, k++); //打印該次排序的結果
if(flag == 0) break;
}
while(k++ < n) print(data, length, k);
return 0;
}
int print(int data[], int length, int k)
{
int j = 0;
printf("The %d-order is:\n", k);
for(j = 0; j < length; j++)
{
printf("%-6d", data[j]);
}
printf("\n");
return 0;
}
int main()
{
int data[9] = {7, 2, 4, 9, 1, 6, 8, 10, 11};
bubble_sort(data, 9, 11);
return 0;
}
完成以上3題之後,好好休息一下吧,O(∩_∩)O~
o ci ka ne sa ma ~