C - 冒号排序字符串数组,然后应用于unsigned int数组

时间:2012-03-23 20:11:42

标签: c arrays sorting

该程序应该采用一个文件,比如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 );

4 个答案:

答案 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

它们是您将用于设置,清除和更改集合中的位的操作。