我正在嘗試為某些字符決議檔案(僅限于可讀的 ASCII)。然后我想列印出字符及其計數,按計數順序,然后按令牌順序。一個明顯的資料結構是哈希圖,就像 C 的 STL 中提供的那樣,然后將值轉儲到向量中進行排序。但是這些都不是在 C 中現成的。
我正在考慮做一個由 ASCII 值索引的對(結構)陣列,然后對陣列進行排序。有沒有更好、更優化的選擇?還有比這更容易實作的嗎?我對 C 很陌生,所以我不習慣它的基本原理。
uj5u.com熱心網友回復:
正如@JB-MSI 已經回答的那樣,您只需要一個陣列即可進行計數。對于第二部分(排序),您可以使用qsort()
來自stdlib.h
.
為了避免全域變數(傳遞給的謂詞函式qsort
缺少背景關系引數,因為該舊語言中有許多舊函式),您需要將字符及其計數打包到一個結構中,然后按計數排序。所以它看起來比實際上要復雜一些,這是 1965 年 C 標準庫設計者啟蒙的恩典。
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#define NCHARS 256
bool character_count(const char* str,
size_t* frequencies,
size_t nfrequencies) {
if (NULL == frequencies)
return false;
if (nfrequencies < 256)
return false;
for (;*str != '\0'; str ) {
frequencies[*str] ;
}
return true;
}
typedef struct CharCount_tag {
char c;
size_t count;
} CharCount_t;
int charcount_compare(const void* cc1, const void* cc2) {
CharCount_t* c1 = (CharCount_t*)cc1;
CharCount_t* c2 = (CharCount_t*)cc2;
if (c1->count == c2->count)
return 0;
else if (c1->count > c2->count)
return -1;
else
return 1;
}
int main (int argc, const char* argv[]) {
if (argc > 1) {
size_t frequencies[NCHARS];
for (size_t i = 0; i < NCHARS; i ) {
frequencies[i] = 0;
}
if (character_count(argv[1], frequencies, NCHARS)) {
CharCount_t cc[NCHARS];
for (size_t i = 0; i < NCHARS; i ) {
cc[i].c = (char) i;
cc[i].count = frequencies[i];
}
qsort(cc, NCHARS, sizeof(cc[0]), charcount_compare);
for (size_t i = 0; i < NCHARS; i ) {
printf("%d (%c) %zu\n", cc[i].c, cc[i].c, cc[i].count);
}
}
}
return 0;
}
uj5u.com熱心網友回復:
這是兩個替代版本。顯然通過掃描編譯時字串來作業。很容易使它適應從打開的檔案中掃描字符。
#include <stdio.h>
#include <stdlib.h>
char *ASCIItbl =
"NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI "
"DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US "
"SP ! \" # $ % & ' ( ) * , - . / "
" 0 1 2 3 4 5 6 7 8 9 : ; < = > ? "
" @ A B C D E F G H I J K L M N O "
" P Q R S T U V W X Y Z [ \\ ] ^ _ "
" ` a b c d e f g h i j k l m n o "
" p q r s t u v w x y z { | } ~ DEL";
char *smpl = "I wish I was\n\twhat I was\nwhen I wished I was\n\twhat I am now.\n";
int main() {
printf( "%s\n", smpl );
int i;
size_t cnt[ 128 1 ]; // built for 7-bit ASCII
memset( cnt, 0, sizeof cnt );
int maxIND = 0;
for( char *cp = smpl; *cp; cp ) { // count while tracking most frequent
cnt[ *cp ] ;
if( cnt[ maxIND ] < cnt[ *cp ] )
maxIND = cp - smpl;
}
#if 1
// output most frequent while scanning for next most freq
printf( "Descending order of frequency:\n" );
int nxtInd = 128;
do {
nxtInd = 128;
for( i = 0; i < sizeof cnt/sizeof cnt[0]; i )
if( cnt[ i ] == cnt[ maxIND ] )
printf( "M %.3s\n", cnt[ maxIND ], &ASCIItbl[ 3*i ] );
else if( cnt[ i ] && cnt[ i ] < cnt[ maxIND ] && cnt[ i ] > cnt[ nxtInd ] )
nxtInd = i;
} while( ( maxIND = nxtInd ) != 128 );
// simple output of non-zero counts in ascending ASCII order
printf( "Ascending order of ASCII value:\n" );
for( i = 0; i < sizeof cnt/sizeof cnt[0] - 1; i )
if( cnt[ i ] )
printf( "M %.3s\n", cnt[ i ], &ASCIItbl[ 3*i ] );
#else
// Output side-by-side
printf( "frequency ASCII seqn\n" );
int idx = 0, nxtInd = 128;
do {
nxtInd = 128;
for( i = 0; i < sizeof cnt/sizeof cnt[0]; i )
if( cnt[ i ] == cnt[ maxIND ] ) {
printf( "M %.3s", cnt[ maxIND ], &ASCIItbl[ 3*i ] );
while( !cnt[ idx] ) ;
printf( "\tM %.3s\n", cnt[ idx ], &ASCIItbl[ 3*idx ] );
} else if( cnt[ i ] && cnt[ i ] < cnt[ maxIND ] && cnt[ i ] > cnt[ nxtInd ] )
nxtInd = i;
} while( ( maxIND = nxtInd ) != 128 );
#endif
return 0;
}
輸出(來自上層版本):
I wish I was
what I was
when I wished I was
what I am now.
Descending order of frequency:
12 SP
9 w
6 I
6 a
5 h
5 s
4 LF
2 HT
2 e
2 i
2 n
2 t
1 .
1 d
1 m
1 o
Ascending order of ASCII value:
2 HT
4 LF
12 SP
1 .
6 I
6 a
1 d
2 e
5 h
2 i
1 m
2 n
1 o
5 s
2 t
9 w
uj5u.com熱心網友回復:
如果您在談論字符的出現?您可以使用基本陣列。(這是純 c ,僅限 ansi 但您可以根據需要進行調整)
void countchar(const char * str, int &charcount[256])
{
for (x = 0; x < strlen(str); c )
{
if (isalpha(str[x])) // optional
charcount[(int)str[x])] ;
}
}
假設傳遞的陣列已初始化!
編輯 1: // 你的基本排序函式
void swap(int* f, int* l)
{
int temp = *f;
*f = *l;
*l = temp;
}
void sortcount(int &charcount[256])
{
int i, j, min_idx;
for (i = 0; i < 256; i ) {
min_idx = i;
for (j = i 1; j < 256; j )
if (charcount[j] < charcount[min_idx])
min_idx = j;
swap(&charcount[min_idx], &charcount[i]);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505895.html