使用c语言使得输入第一行输入测试次数t,t表示测试的组数,然后输入每组的测试数据,测试数据为一行字符串,最后对每组数据输出字符串中按顺序出现的碎片和所有碎片的平均长度(所有碎片的平均长度 = 所有碎片长度之和/碎片个数,且相同碎片只输出一次,平均长度保留2位小数),请给出完整的代码实现。
时间: 2024-02-20 13:59:29 浏览: 61
好的,下面是完整的代码实现。在代码中,我们使用了哈希表来统计字符串中出现的碎片及其出现次数,使用了动态数组来存储所有的碎片,最后统计所有碎片的长度并计算平均长度。注意,在计算平均长度时,需要将结果保留2位小数,可以使用 printf 函数的 %.2f 格式控制符实现。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100 // 假设字符串最大长度为100
// 哈希表节点
typedef struct HashNode {
char *key; // 碎片
int value; // 出现次数
struct HashNode *next; // 下一个节点
} HashNode;
// 哈希表
typedef struct {
HashNode **buckets; // 桶数组
int size; // 桶数组大小
} HashMap;
// 动态数组
typedef struct {
char **data; // 数据
int size; // 大小
int capacity; // 容量
} DynamicArray;
// 初始化哈希表
void HashMapInit(HashMap *hm, int size) {
hm->buckets = (HashNode **)malloc(sizeof(HashNode *) * size);
hm->size = size;
memset(hm->buckets, 0, sizeof(HashNode *) * size);
}
// 哈希函数
int HashFunc(char *key) {
int hash = 0;
while (*key) {
hash = (hash * 31 + *key) % MAX_LEN;
key++;
}
return hash;
}
// 插入节点
void HashMapInsert(HashMap *hm, char *key) {
int hash = HashFunc(key);
HashNode *node = hm->buckets[hash];
while (node) {
if (strcmp(node->key, key) == 0) { // 碎片已存在,增加出现次数
node->value++;
return;
}
node = node->next;
}
// 碎片不存在,新建节点
node = (HashNode *)malloc(sizeof(HashNode));
node->key = (char *)malloc(sizeof(char) * (strlen(key) + 1));
strcpy(node->key, key);
node->value = 1;
node->next = hm->buckets[hash];
hm->buckets[hash] = node;
}
// 销毁哈希表
void HashMapDestroy(HashMap *hm) {
for (int i = 0; i < hm->size; i++) {
HashNode *node = hm->buckets[i];
while (node) {
HashNode *next = node->next;
free(node->key);
free(node);
node = next;
}
}
free(hm->buckets);
}
// 初始化动态数组
void DynamicArrayInit(DynamicArray *da) {
da->data = (char **)malloc(sizeof(char *) * 1);
da->size = 0;
da->capacity = 1;
}
// 添加元素
void DynamicArrayAdd(DynamicArray *da, char *value) {
if (da->size == da->capacity) { // 扩容
da->capacity *= 2;
da->data = (char **)realloc(da->data, sizeof(char *) * da->capacity);
}
da->data[da->size] = (char *)malloc(sizeof(char) * (strlen(value) + 1));
strcpy(da->data[da->size], value);
da->size++;
}
// 销毁动态数组
void DynamicArrayDestroy(DynamicArray *da) {
for (int i = 0; i < da->size; i++) {
free(da->data[i]);
}
free(da->data);
}
int main() {
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++) {
char str[MAX_LEN + 1];
scanf("%s", str);
HashMap hm;
HashMapInit(&hm, MAX_LEN);
int len = strlen(str);
for (int j = 0; j < len; j++) {
for (int k = j; k < len; k++) {
char *sub = (char *)malloc(sizeof(char) * (k - j + 2));
strncpy(sub, str + j, k - j + 1);
sub[k - j + 1] = '\0';
HashMapInsert(&hm, sub);
free(sub);
}
}
DynamicArray da;
DynamicArrayInit(&da);
int count = 0;
int total_len = 0;
for (int j = 0; j < hm.size; j++) {
HashNode *node = hm.buckets[j];
while (node) {
DynamicArrayAdd(&da, node->key);
count++;
total_len += strlen(node->key);
node = node->next;
}
}
// 冒泡排序
for (int j = 0; j < da.size - 1; j++) {
for (int k = 0; k < da.size - 1 - j; k++) {
if (strcmp(da.data[k], da.data[k + 1]) > 0) {
char *temp = da.data[k];
da.data[k] = da.data[k + 1];
da.data[k + 1] = temp;
}
}
}
// 输出碎片
for (int j = 0; j < da.size; j++) {
printf("%s ", da.data[j]);
}
printf("\n");
// 输出平均长度
printf("%.2f\n", (float)total_len / count);
// 销毁哈希表和动态数组
HashMapDestroy(&hm);
DynamicArrayDestroy(&da);
}
return 0;
}
```
阅读全文