繁体   English   中英

C-对字符串进行冒泡排序数组,然后应用于无符号int数组

[英]C - Bubble sort array of character strings, then apply to unsigned int array

该程序应该获取一个文件,例如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];

作为名称数组的索引。 因此,每个无符号整数都有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 );

实际上,您的气泡排序不是气泡排序。 它仅对数组进行一次传递。 您需要反复遍历数组,直到进行不导致交换的遍历为止。 到那时,您知道阵列已排序。

我首选的冒泡排序实现有一个外部do循环。 内部循环与您当前的状态相同。 当最新的内部循环执行未能交换任何项目时,外部循环终止。

当然,从长远来看,我建议使用更好的排序算法,但这可能是一项家庭作业。

问题出在这部分:

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);
        }

冒泡排序应该有两个循环! ;-)例如,请参见此处的整数。

Bubblesort执行不正确。 应该有一个内循环和一个外循环。

我不清楚320位集合的用途:它不能用于排序,或用于其他任何东西,除了每个位都表明数组的某些属性为真(例如它是否存在,是否包含动词或一些东西。

总结名称排序独立于设置操作是否公平?

只要名称不变,设置操作是否有效?

您列出的操作分为以下几类:

直集运算,不管它们是什么集合。 它们一次在整个集合上运行:

extern void setUnion(Set set1, Set set2, Set result);
extern void setIntersection(Set set1, Set set2, Set result);
extern void clearSet(Set 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)]&(1 <<(value%32))

那么您了解位运算符吗?

~ not
& and
| or
^ xor
<< left shift
>> right shift

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM