HJ19错误简单记录

本文详细介绍了在C语言中实现循环队列及其操作,包括队列的初始化、判断队列空满、字符串去重功能的开发,以及遇到的问题如脏数据和逻辑调整。
摘要由CSDN通过智能技术生成

提示:文章

文章目录

前言

前期疑问:
本文目标:


一、背景

最近

二、

2.1 代码

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "stdlib.h"

#define DSR_STR_LEN 16
#define DEQUE_FULL  true
#define DEQUEUE_EMPTY false

typedef struct
{
    char str[DSR_STR_LEN * 2];
    int count;
}LogInfo;

typedef struct
{
    int head;
    int rear;
    LogInfo info[8];
}Queue, *pQueue;

bool isQueueEmpty(Queue queue)
{
    if(queue.rear == queue.head)
    {
        return DEQUEUE_EMPTY;
    }

    return DEQUE_FULL;
}

void DequePush(Queue* queue, LogInfo* info)
{
    if(queue->rear < 8)
    {
        memcpy(&queue->info[queue->rear], info, sizeof(LogInfo));
        queue->rear++;
    }
    else if(queue->rear >= 8)
    {
        queue->head++;
        int rear = queue->rear % 8;
        
        memcpy(&queue->info[rear], info, sizeof(LogInfo));
        queue->rear++;
    }
}

void getTargetStr(char* str)
{
    int lenOfStr = strlen(str);
    char* strCopy = (char*)malloc(sizeof(char) * lenOfStr + 1);
    memset(strCopy, '\0', lenOfStr);
    strcpy(strCopy, str);
    char* token = strtok(strCopy, " ");
    if(token != NULL)
    {
        int len = strlen(token);
        if(len > DSR_STR_LEN)
        {
            int i = 0;
            int index = 0;
            while(i < lenOfStr)
            {
                str[index] = str[len - DSR_STR_LEN + index];
                index++;
                i++;
            }
        }
    }
    free(strCopy);
}  

bool isWithoutSameStr(Queue* queue, char* str, char (*p)[DSR_STR_LEN * 2], int count)
{
    
    for(int i = 0; i < 8; i++)
    {
        if(strcmp(queue->info[i % 8].str, str) == 0)
        {
            queue->info[i % 8].count++;
            return false;
        }
    }
    for(int i = 0; i < count - 1; i++)
    {
        if(strcmp(p[i], str) == 0)
        {
            return false;
        }
    }
    return true;
}

void printQueueTest(Queue* queue)
{
    for(int i = 0; i < 8; i++)
    {
        printf("0:%s %d\n", queue->info[i % 8].str, queue->info[(queue->head + i) % 8].count);
    }
}

void printQueue(Queue* queue)
{
    for(int i = 0; i < 8; i++)
    {
        if(strlen(queue->info[(queue->head + i) % 8].str) > 0)
        {
            printf("%s %d\n", queue->info[(queue->head + i) % 8].str, queue->info[(queue->head + i) % 8].count);
        }
    }
}

Queue g_queue;
int main() {
    char str[101] = {'\0'};
    char strToken[DSR_STR_LEN] = {'\0'};
    char strDictionary[101][DSR_STR_LEN * 2];
    int strDictionaryIndex = 0;
    while (fgets(str, 101, stdin) != NULL) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to 
        strtok(str, "\n");
        char* token = strtok(str, "\\");
        while(token != NULL)
        {
            memset(strToken, '\0', DSR_STR_LEN);
            strcpy(strToken, token);
            token = strtok(NULL, "\\");
        }
        getTargetStr(strToken);
        //printf("22dst:%s\n", strToken);
        strcpy(strDictionary[strDictionaryIndex++], strToken);
       
        if(isWithoutSameStr(&g_queue, strToken, strDictionary, strDictionaryIndex))
        {
            LogInfo info;
            info.count = 1;
            //printf("1:%s\n", strToken);
            strcpy(info.str, strToken);
            DequePush(&g_queue, &info);
            memset(info.str, '\0', DSR_STR_LEN * 2);
        }
    }
    //printQueueTest(&g_queue);
    //printf("head:%d rear%d\n", g_queue.head, g_queue.rear);
    printQueue(&g_queue);
    return 0;
}

本文经过多次调试实现,

回顾题目完成过程中,首先遇到的问题是一开始准备用循环队列。最后使用了数组,但是数组读取存储方式是按照首尾循环读取的。其中有不少关于for循环的不精确等问题。

然后遇到的额一个关键问题就是,LogInfo info;局部变量,存过一次字符串后,没有memset,导致后面继续插入的时候有脏数据,导致程序异常。

另一个问题是逻辑问题,就是对于新的字符串,我一开始只与8个存入数组(vector)中的字符串比较是否相同。但是这边有个问题 ,就是题目中描述,只要出现过都不记录。【只以第一次出现的顺序为准,后面重复的不会更新它的出现时间】,所以不能仅仅与长度为8的数组比较,因为长度为8的数组是溢出方案,要将所有字符串都存储再比较,否则程序异常。

2.2

三、

3.1


总结

未完待续

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值