【C语言算法实现】计算数字 k 在 【0,n】中的出现的次数,k 可能是 0~9 的一个值。

cocowy的编程之旅

C语言实现
lincode算法题

  • 前言
  • 网上其他的csdn博客上有很多对于这个题的算法实现,但到目前为止,使用C语言来进行代码复现并且算法思维和边界条件正确并且呈现给大家的一清二楚的没有几个,我这篇文章权当抛砖引玉,期待高手留言。

问题描述:
在这里插入图片描述

算法思维

通过题目描述我们可以很容易的得到其中心思想,简而言之就是数数,在[0,n]的区间里找出出现过k的次数,我们可以自然而然的想到,对区间中的每一个数进行遍历然后每一个数都对其取余数,与k比较,若与k相等则计数器加一,反之。但是!!!对于k=0来说,计数器要多加一个1,原因是0出现过一次!!!总而言之,就是要考虑到边界条件K=0这种情况!
代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main()
{
int i,j,t;
int cnt0=0;//对于k>0时候的计数器
int cnt1=1;//对于k=0时候的计数器
int k,n;
int prime=1;//利用变量将其区分
scanf("%d %d",&k,&n);
printf("k=%d,n=%d",k,n);
 for(i=0;i<=n;i++)
{
    int ret=0;
	t=i;
	//t=200;
	while(k==0&&t>0)
	{
		prime=0;	
		ret=t%10;
		t/=10;
		if(ret==0)
		  cnt1++;
	}
	while(k>0&&t>0&&n>0)//k>0的情况 
	{
		ret=t%10;
		if(k==ret)
		  cnt0++;
		t/=10;
	}	 
}
if(prime)
printf("在[0,%d]中,我们发现了%d出现了%d次",n,k,cnt0);	
else
printf("在[0,%d]中,我们发现了%d出现了%d次",n,k,cnt1);	
return 0;
} 

对于k=0的特殊情况==在这里插入图片描述

对于k>0d的情况这里是引用

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 答:可以使用归并排序算法计算反转次数。归并排序的过程分为两个步骤,其第一步是将数组分解成若干个独立的小数组,然后在第二步归并它们。在归并的过程,可以记录反转的次数,它的复杂度为O(n log n)。具体的实现可以参考下面的C代码: int merge_sort(int arr[], int l, int r) { int count = 0; if (l < r) { int m = l+(r-l)/2; count += merge_sort(arr, l, m); count += merge_sort(arr, m+1, r); count += merge(arr, l, m, r); } return count; } int merge(int arr[], int l, int m, int r) { int count = 0; int n1 = m - l + 1; int n2 = r - m; int L[n1], R[n2]; for (int i = 0; i < n1; i++) L[i] = arr[l + i]; for (int j = 0; j < n2; j++) R[j] = arr[m + 1+ j]; int i = 0, j = 0; int k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; // 如果右边的数小于左边的数,则计数器加上右边剩余数的个数 count = count + (n1 - i); } k++; } while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } return count; } ### 回答2: 给定一个数字序列a,计算逆序次数算法可以通过归并排序的方式实现,其时间复杂度为O(n log n)。 算法步骤如下: 1. 将数字序列a拆分成两个子序列,分别为左子序列和右子序列。 2. 对左子序列和右子序列分别进行递归调用,直到子序列只有一个数字。 3. 对两个子序列进行合并操作,合并排序后的结果存储在一个临时数组。 4. 在合并的过程,如果左子序列数字大于右子序列数字,则计算逆序次数。 5. 将合并排序后的结果复制回原始数组a。 以下是使用C语言实现算法的代码示例: ```c #include <stdio.h> int merge(int arr[], int temp[], int left, int mid, int right){ int i = left, j = mid, k = left, count = 0; while(i <= mid-1 && j <= right){ if(arr[i] <= arr[j]){ temp[k++] = arr[i++]; } else{ temp[k++] = arr[j++]; count += mid - i; } } while(i <= mid - 1){ temp[k++] = arr[i++]; } while(j <= right){ temp[k++] = arr[j++]; } for(i = left; i <= right; i++){ arr[i] = temp[i]; } return count; } int mergeSort(int arr[], int temp[], int left, int right){ int mid, count = 0; if(right > left){ mid = (left + right) / 2; count += mergeSort(arr, temp, left, mid); count += mergeSort(arr, temp, mid+1, right); count += merge(arr, temp, left, mid+1, right); } return count; } int getInverseCount(int arr[], int n){ int temp[n]; return mergeSort(arr, temp, 0, n-1); } int main(){ int arr[] = {3, 1, 2, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]); int inverseCount = getInverseCount(arr, n); printf("逆序次数: %d\n", inverseCount); return 0; } ``` 该算法通过归并排序的方式将数组进行排序,并在排序的过程计算逆序次数。在主函数给定一个数组arr并调用getInverseCount函数,可以得到该数组的逆序次数。以上代码输出的结果为:逆序次数: 3。 ### 回答3: 逆序次数算法可以用分治算法来设计。具体步骤如下: 1. 首先将原始序列a分成两个子序列a1和a2,分别计算出a1和a2的逆序次数,递归地调用该算法。 2. 然后将a1和a2归并排序得到有序的序列b。在归并排序的过程,可以计算出a1和a2之间的逆序对数目。 3. 将b重新合并成原始序列a。 这个算法的时间复杂度为O(n log n)。具体的C代码如下: ```c #include <stdio.h> // 合并两个有序序列并计算逆序次数 int merge(int arr[], int temp[], int left, int mid, int right) { int i = left, j = mid + 1, k = left; int count = 0; while (i <= mid && j <= right) { if (arr[i] > arr[j]) { temp[k++] = arr[j++]; // 如果arr[i] > arr[j],说明存在逆序对,逆序次数加上 j-mid count += mid - i + 1; } else { temp[k++] = arr[i++]; } } while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } for (int m = left; m <= right; m++) { arr[m] = temp[m]; } return count; } // 归并排序并计算逆序次数 int mergeSort(int arr[], int temp[], int left, int right) { int count = 0; if (left < right) { int mid = (left + right) / 2; count += mergeSort(arr, temp, left, mid); count += mergeSort(arr, temp, mid + 1, right); count += merge(arr, temp, left, mid, right); } return count; } int main() { int arr[] = {5, 2, 6, 1, 3, 7}; int n = sizeof(arr) / sizeof(arr[0]); int temp[n]; int count = mergeSort(arr, temp, 0, n - 1); printf("逆序次数:%d\n", count); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值