字符串中找出连续最长的数字串 &&n个数里出现次数大于等于n/2的数

本文深入解析了指针数组与数组指针的概念,通过实例阐明了二维数组的初始化省略技巧,并提供了两道编程挑战题的解题思路,包括寻找最长连续数字串与定位多数元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、概念笔记

①指针数组与指针数组

对于 A)int *p1[10]B)int (*p2)[10]
“ [ ] ”的优先级比“ * ” 要高。p1 先与“[ ]”结合,构成一个数组的定义,数组名为p1,int* 修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组
“()”的优先级比“[]”高,“*”号和p2构成一个指针的定义,指针变量名为p2,int修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组,p2是一个指针,它指向一个包含10个int类型数据的数组即数组指针

②二维数组的初始化省略

二维数组的第一维可以看作是一个数组指针即(*arr)[ ],利用数组指针进行访问,因此二维数组的初始化可以省略第一维,但不可省略第二维
如:int ta[][3]={{0,1,2},{3,4,5}};

2、OJ编程

1、字符串中找出连续最长的数字串

读入一个字符串str,输出字符串str中的连续最长的数字串
解:这道题比较简单,遍历字符串,只要判定是数字字符,进入循环++ count,直到遍历到不是数字字符,然后保存这个值,继续遍历,如果后面有比这个值大的就覆盖这个值,知道遍历完这个字符串。
例如:abcd12345ed125ss123456789。

cur_str:当前数字字符串
ret_str:保存的数字字符长度
if(该字符c属于数字字符)
{
	while(该字符c属于数字字符 && 字符串未遍历完)
	{
		cur_str += c;
	}
	if(cur_str.size() > ret_str.size())
		cur_str= cur_str;
	cur_str.clear();
}

2、n个数里出现次数大于等于n/2的数

输入n个整数,输出出现次数大于等于数组长度一半的数。

解:简单的解法就是把数组排序,然后输出最中间的那个数。因为它出现的次数大于数组长度的一半,那么排序之后,肯定有一个数在中间。当然也可以用map来做,用一个map来记录出现的次数,然后遍历这个map就行。

    int n;
    int size = 0;
    map<int,int> m;
    
    while(cin >> n)
    {
        ++m[n];
        ++size;
    }
    for(const auto& m : m)
        if(m.second >= size/2)
        {
            cout << m.first << endl;
            break;
        }

3、源代码地址

上述两道题的参考代码链接,点击题目就可进入。

### C语言中查找数组中出现次数最多的 在C语言中,可以通过遍历数组并记录各个元素出现的频率来找到出现次数最多的。下面提供一种简单而有效的实现方式。 #### 方法一:使用哈希表(适用于已知范围内的整型据) 当处理的是有限范围内(如0-9之间的数字)的据时,可以直接利用辅助数组作为简单的哈希表来进行计: ```c #include <stdio.h> #define SIZE 10 /* 假设只考虑'0'- '9' */ void countDigits(const char *str) { int counts[SIZE] = {0}; // 初始化为全零 while (*str != '\0') { if ('0' <= *str && *str <= '9') ++counts[*str - '0']; // 记录对应位置上的量增加 str++; } printf("各数字出现频次如下:\n"); for (int i = 0; i < SIZE; ++i) printf("%d 出现 %d 次\n", i, counts[i]); } ``` 这段代码展示了如何统计一个字符串中的每一个数字字符('0'-'9')各自的出现次数[^1]。 对于更通用的情况——即不限定于特定区间内取值的情况下,则可以采用其他策略,比如先对数组排序再找最大连续相同项的量;或者是通过两次扫描完成任务,在第一次扫描过程中选出候选者,并验证该候选人是否真的超过半以上[^2]。 #### 方法二:Boyer-Moore 投票算法 这种方法特别适合用来解决“多投票问题”,也就是在一个长度为`N`的序列寻找是否存在某个元素出现了大于`⌊ N / 2 ⌋`次的情形。此方法的时间复杂度仅为O(n),空间复杂度为常量级别O(1): ```c int majorityElement(int* nums, int numsSize){ int candidate = nums[0], vote = 1; for (int i = 1; i < numsSize; ++i) { if (!vote) { candidate = nums[i]; vote = 1; } else if (nums[i] == candidate) ++vote; else --vote; } // 验证candidate确实超过了半 int frequency = 0; for (int j = 0; j < numsSize; ++j) if (nums[j] == candidate) ++frequency; return frequency > numsSize / 2 ? candidate : -1; } ``` 上述函实现了Boyer-Moore投票算法的核心逻辑,用于检测给定数组中是否有任何一个元素占据了过半的位置。 如果目标不是严格意义上的大多元素而是单纯想要知道哪个元素最频繁地出现,那么还可以采取另一种方案,就是创建额外的空间存储每个不同元素及其对应的计值,最后比较这些计值得出结果[^3]。 #### 方法三:双重循环暴力求解法 这是一种较为直观但也效率较低的方法,它会两层嵌套迭代整个输入集合,外层固定当前考察对象,内层则负责计算这个对象在整个集合同类成员总: ```c typedef struct { int value; int freq; } ElementFrequencyPair; // ...省略部分初始化工作... for (size_t outerIndex = 0; outerIndex < arrayLength; ++outerIndex) { bool isNewEntry = true; for (size_t innerIndex = 0; innerIndex < resultCount; ++innerIndex) { if (elements[resultIndices[innerIndex]].value == elements[outerIndex].value) { elements[resultIndices[innerIndex]].freq += 1; isNewEntry = false; break; } } if (isNewEntry) { elements[arrayLength + resultCount++] = (ElementFrequencyPair){ .value = elements[outerIndex].value, .freq = 1 }; } } // 接下来可以根据resultCounts[]的信息进一步分析... ``` 这种做法虽然容易理解但是性能较差,尤其是在面对大据集的时候不推荐使用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值