问题是根据频率对数组进行排序 元素。例如,如果输入数组是
{ 2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12 }
然后将数组修改为:
{ 3, 3, 3, 3, 2, 2, 2, 12, 12, 4, 5 }
我为此编写了代码并且它正常工作,但是它使用了大量空间并且具有非常高的复杂性。
我对此解决方案以及我为此应用的逻辑感到不满意。如果有人帮助优化此代码或提供更好的逻辑。
我的代码是:
#define _CRT_SECURE_NO_WARNINGS // this line to work code in visual studio
#include <stdio.h>
int main() {
/*
* n = number of integer
* i = loop variable
* j = inner loop variable
* c = number of distinct input
* buf = temprary storage for input value
* k = possibility of frequency of any no.
*/
int n, i, j, c = 0, buf, k;
int b; //act as flag
int arr[100] = { 0 };
int stack[200] = { 0 };
int top = -1;
printf("Enter the size of array(integer between 1-100):");
scanf("%d", &n);
n *= 2;
printf("----------Enter the elements in the array----------\n\n");
for (i = 0; i < n; i += 2) {
b = 0;
printf("Enter the element:");
scanf("%d", &buf);
for (j = 0; j <= i; j += 2) {
if (arr[j] == buf) {
arr[j + 1]++;
b = 1;
}
}
if (b == 0) {
c++;
arr[c * 2 - 2] = buf;
arr[c * 2 - 1]++;
}
}
for (i = 0; i < c * 2; i++)
printf("%d ", arr[i]);
//input done in form of (element,times of occurence i.e. frequency),to print array, write this outside of comment:
//for (i = 0; i < c * 2; i++) printf("%d ", arr[i]);
for (k = 1; k < n / 2; k++) { //checking for possible frequencies
for (j = c * 2 - 1; j > 0; j -= 2) {
//locations(index) to check in array for frequency
//left to right, so with same frequency no.,which occurred first will push in last.
if (arr[j] == k)
stack[++top] = j; //pushing(index of frequency) into stack in increasing order of frequency
}
}
//to print stack, write this outside of comment:
//printf("\nstack\n");
//for (i = top; i > -1; i--) printf("%d ",stack[i]);
//printing of elements in there decreasing order of frequency(pop from stack)
//we have to print element, number of times of its frequency
printf("\n\n----------Output array in sorted order of there frequency----------\n");
for (top; top > -1; top--) {
for (j = arr[stack[top]]; j > 0; j--)
printf("%d ", arr[stack[top] - 1]);
}
}
答案 0 :(得分:1)
我用一些新的方法和逻辑非常简单有效地解决了这个问题。
def func(val):
for key, value in dict1.items():
if val == value:
return key
res=[]
for _ in range(int(input())):
n=int(input())
lst=list(map(int,input().split()))
dict1={}
lst.sort()
lst2=[]
for i in lst:
dict1[i]=lst.count(i)
lst2.append(lst.count(i))
lst2.sort()
lst2.reverse()
s=''
for i in lst2:
k=func(i)
s=s+((str(k)+" ")*i)
dict1[k]=0
s1=s.replace('None',"")
s2=s1.replace(" ","")
res.append(s2)
for i in res:
print(i)
答案 1 :(得分:0)
如果 O(N 2 )并且 O(N)的平均复杂度,我找到了一种优雅的方法来执行这种最坏情况复杂的情况.LOG(N))强>
该方法使用以下步骤:
qsort
和一个简单的比较函数。以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int int_cmp(const void *p1, const void *p2) {
int i1 = *(const int *)p1;
int i2 = *(const int *)p2;
return (i1 > i2) - (i1 < i2);
}
void print_array(const char *msg, const int *a, int n) {
printf("%s: ", msg);
for (int i = 0; i < n; i++)
printf("%d%c", a[i], " \n"[i == n - 1]);
}
int main(int argc, char *argv[]) {
int N = argc > 1 ? atoi(argv[1]) : 200;
int *array;
if (N <= 0 || (array = calloc(N, sizeof(*array))) == NULL)
return 1;
srand(N);
for (int i = 0; i < N; i++) {
unsigned int x = rand();
array[i] = x * x % 10;
}
print_array("unsorted", array, N);
qsort(array, N, sizeof(int), int_cmp);
print_array(" sorted", array, N);
/* sort by decrasing frequency (assuming N > 0) */
for (int i = 0;;) {
/* find the most repeated sequence in [i..N-1] */
int rep = array[i];
int n = 1, j, k;
for (j = k = i + 1; j < N; j++) {
if (array[j] == array[j - n]) {
rep = array[j];
k = j + 1;
n++;
}
}
if (n == 1) {
/* no more duplicates, f-sort completed */
break;
}
i += n;
if (k > i) {
/* shift the repeated sequence in place */
while (k-- > i) {
array[k] = array[k - n];
}
while (n-- > 0) {
array[k--] = rep;
}
}
}
print_array("f-sorted", array, N);
free(array);
return 0;
}
答案 2 :(得分:0)
您可以从bucket sort的修改版本开始,但在创建存储桶列表后中途停止。
我做了这个,受到了斗式的启发。它最弱的链接是快速排序,但我可以修改它以使用桶排序。我估计长度为n且最大值为m的数组A的复杂度为O(m + n log n),如果使用bucket sort而不是qsort进行修改,则会降低到O(m + n)
typedef struct {
int bucket;
int index;
} element;
int compare(const void *a, const void *b)
{
element *A = (element *) a;
element *B = (element *) b;
return(A->bucket < B->bucket);
}
void sortByFreq(int * arr, int len)
{
int arrMax=findMax(arr, len); // O(len)
element x[arrMax+1];
for(int i=0; i<=arrMax; i++) { // O(arrMax)
x[i].bucket=0;
x[i].index=i;
}
for(int i=0; i<len; i++) // O(len)
x[arr[i]].bucket++;
qsort(x, arrMax+1, sizeof(element), compare); //O(len*log(len))
int k=0;
for(int i=0; i<=arrMax; i++) // O(arrMax + len)
for(int j=0; j<x[i].bucket; j++)
arr[k++]=x[i].index;
}
答案 3 :(得分:0)
1)创建一个二进制搜索树,并在创建BST的同时保持同一BST中每个即将到来的元素的计数。如果使用自平衡BST,则此步骤可能需要O(nLogn)时间。
2)进行BST的有序遍历,并将每个元素和每个元素的计数存储在辅助数组中。让我们将辅助数组称为“ count []”。注意,该阵列的每个元素都是元素和频率对。此步骤需要O(n)时间。
3)根据元素的频率对“ count []”进行排序。如果使用O(nLogn)排序算法,则此步骤需要O(nLohn)时间。
4)遍历排序数组“ count []”。对于每个元素x,请按“频率”倍数打印,其中“频率”是x的频率。此步骤需要O(n)时间。
如果我们使用O(nLogn)排序算法并使用具有O(Logn)插入操作的自平衡BST,则该算法的总体时间复杂度可以为最小O(nLogn)。
source
答案 4 :(得分:0)
按值对数组进行排序; RLE结果,将每个equals变成一对元素和该span的长度(可以使用辅助数组来支持第二个组件);对第二对组件按降序排序;有你的结果。全部用 O(n log n)时间和 O(n)附加空间。
答案 5 :(得分:0)
#include<stdio.h>
#include<malloc.h>
int* freq_sort_array(int*,int);
int main()
{
int a[10]={7,0,0,5,0,0,0,0,0,0}; /*input array*/
int *b,i;
printf("Input Array\n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
b=freq_sort_array(a,10);
printf("\nOutput array\n");
for(i=0;i<10;i++)
printf("%d ",b[i]);
}
/*Function for sorting array based on frequency*/
int* freq_sort_array(int *a,int len)
{
int i,j,temp,count,k=0,s=0,t=0;
int *b=(int*)malloc(len*sizeof(int));
int *c=(int*)malloc(len*sizeof(int));
for(i=0;i<len;i++)
{
for(j=i+1;j<len;j++)
{
if(a[j]==a[i])
{
temp=a[j];
for(j;j>i+1;j--)
{
a[j]=a[j-1];
}
a[++i]=temp;
}
}
}
for(i=0;i<len;i++)
{
a[j]=a[i];
count=1;
if(i!=len-1)
{
while(a[++i]==a[j]&& i<len)
count++;
i=i-1;
}
b[k]=a[j];
c[k++]=count;
}
for(i=1;i<k;i++)
{
for(j=0;j<k-i;j++)
{
if(c[j]<c[j+1])
{
c[j]=c[j]+c[j+1]-(c[j+1]=c[j]);
b[j]=b[j]+b[j+1]-(b[j+1]=b[j]);
}
}
}
for(i=0;i<k;i++)
{
for(j=0;j<c[i];j++)
a[s++]=b[i];
}
return a;
}
答案 6 :(得分:0)
这里是一种使用qsort
的实现方式,用于对值进行排序以轻松计算频率,并通过降低频率对结果频率表进行排序。当两个值具有相同的频率时,我们通过增加值进行排序。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int cmp_int(const void *p1, const void *p2) {
return *(const int *)p1 - *(const int *)p2;
}
typedef struct {
int val;
int cnt;
} freq;
int cmp_freq(const void *p1, const void *p2) {
const freq *pf1 = (const freq *)p1;
const freq *pf2 = (const freq *)p2;
if(pf1->cnt == pf2->cnt)
return pf1->val - pf2->val;
return pf2->cnt - pf1->cnt;
}
void frequencySort(int tbl[], int n) {
// sort values in ascending order
qsort(tbl, n, sizeof(int), cmp_int);
// fill frequency table with frequencies
int nFreq = 0;
freq *freqTbl = malloc(n*sizeof(freq));
int val = tbl[0];
int cnt = 1;
for(int i = 1; i < n; i++) {
if(tbl[i] != val) {
freqTbl[nFreq].cnt = cnt;
freqTbl[nFreq].val = val;
nFreq++;
val = tbl[i];
cnt = 1;
} else {
cnt++;
}
}
freqTbl[nFreq].cnt = cnt;
freqTbl[nFreq].val = val;
nFreq++;
// sort by frequencies
qsort(freqTbl, nFreq, sizeof(freq), cmp_freq);
// refill tbl by frequencies
int m = 0;
for(int i = 0; i < nFreq; i++)
for(int j = 0; j < freqTbl[i].cnt; j++)
tbl[m++] = freqTbl[i].val;
free(freqTbl);
}
int main(int argc, char *argv[])
{
int n = argc > 1 ? atoi(argv[1]) : 200;
int *tbl;
if (n <= 0 || (tbl = malloc(n * sizeof(int))) == NULL)
return 1;
srand(time(NULL));
for (int i = 0; i < n; i++)
tbl[i] = abs(rand()) % 10;
printf("[%d", tbl[0]);
for (int i = 1; i < n; i++)
printf(",%d", tbl[i]);
printf("]\n");
frequencySort(tbl, n);
printf("[%d", tbl[0]);
for (int i = 1; i < n; i++)
printf(",%d", tbl[i]);
printf("]\n");
free(tbl);
return 0;
}