该程序应该采用一个文件,比如data.dat,填充最多320个单词的列表,所有单词都小于或等于29个字符(30个带有空字符)并将这些单词添加到全局阵列。然后我想用冒泡排序按字母顺序对该列表进行排序。我在自己的文件sort.c中使用以下函数这样做了。
#include "set.h"
#include "sortAndSearch.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void bubbleSort(char A[][30], int num) {
int i, j;
char temp[30];
for(i = 0; i < num; i++)
for(j = 0; j < num-1; j++)
if(strcmp(A[i], A[i+1]) > 0){
//swap the two array elements
strcpy(temp, A[j]);
strcpy(A[j], A[j+1]);
strcpy(A[j+1], temp);
}
}
我需要一组无符号整数
unsigned int Set[10];
充当names数组的索引。因此每个unsigned int有32位,有10个无符号整数,总共320位,每个位将引用一个字。我不确定如何处理这一部分。
最终目标是创建操作集合的函数。我觉得我可以自己攻击,如果我可以得到排序和索引,因为我已经做了类似的事情,但没有使用字符数组。定义要使用的函数的头文件set.h的内容遵循
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// defining new type(s)
typedef unsigned int Set[10];
// declaring global variable(s)
extern char names[320][30];
extern void setUnion(Set set1, Set set2, Set result);
extern void setIntersection(Set set1, Set set2, Set result);
extern void clearSet(Set set);
extern void add2Set(Set set, int value);
extern void deleteFromSet(Set set, int value);
extern int isMember(Set set, int element);
extern void printSet(Set);
extern int nameIsMember(Set set, char *);
extern void addName2Set(Set set, char *);
extern void deleteNameFromSet(Set set, char *);
以下是头文件sortAndSearch.h
的内容void bubbleSort(char A[][30], int num);
int binarySearch(char A[][30], char *, int, int );
答案 0 :(得分:4)
您的冒泡排序实际上不是冒泡排序。它只对数组进行一次传递。您需要重复传递数组,直到您进行不会导致交换的传递。那时你知道你的数组是有序的。
我首选的冒泡排序实现有一个外部do
循环。内循环就像你现在一样。当最新的内部循环执行无法交换任何项时,外部循环终止。
当然,我建议从长远来看使用更好的排序算法,但这可能是一项家庭作业。
答案 1 :(得分:2)
问题出在这一部分:
for(i = 0; i < num-1; i++)
if(strcmp(A[i], A[i+1]) > 0){
//swap the two array elements
strcpy(temp, A[i]);
strcpy(A[i], A[i+1]);
strcpy(A[i+1], temp);
}
应该是两个循环用于冒泡排序! ;-) 有关整数的信息,请参阅here。
答案 2 :(得分:1)
bubblesort未正确实施。应该有一个内循环和一个外循环。
我不清楚320位集的目的:它不能用于排序,或者除了指示数组的某些属性为真的每个位以外的任何其他内容,例如它是否存在,或者包含动词或其他东西。
答案 3 :(得分:0)
总结一下,名称的排序是否与集合运算无关,这是否公平?
只要名称没有改变,设置操作就会起作用吗?
您列出的操作属于这些组:
直接设置操作,它们是什么组合并不重要。它们一次只能运行一整套:
extern void setUnion(Set set1, Set set2, Set result);
extern void setIntersection(Set set1, Set set2, Set result);
extern void clearSet(Set set);
你可以解决这些问题,而不必担心这个集合可能意味着什么,但是你需要一些价值观才能编码或使用它们。
设置元素操作,这些操作在集合中操作一个位,并且再次不关心这些位代表什么:
extern void add2Set(Set set, int value);
extern void deleteFromSet(Set set, int value);
extern int isMember(Set set, int element);
这是一个很好的起点。
这些操作在名称和集合之间映射,因此需要更多工作:
extern int nameIsMember(Set set, char *);
extern void addName2Set(Set set, char *);
extern void deleteNameFromSet(Set set, char *);
我不确定extern void printSet(Set);
的含义是什么,它是否打印了集合中的名称?
好的,一套是
unsigned int s[10];
要测试一下,我们需要将int值转换为int的索引,以及int中的位。最简单的方法是数组索引=(值/ 32),位偏移量是(值%32)。编译器应该很好地提高效率,所以不要担心效率。
获得s中的位值:(s [(value / 32)]&amp;(1&lt;&lt;(value%32))
您了解bit operators吗?
~ not
& and
| or
^ xor
<< left shift
>> right shift
它们是您将用于设置,清除和更改集合中的位的操作。