我对下面的要求几乎没有帮助,因为我对C语法知之甚少。
我有像这样的文件中的数据
73 54 57 [52]
75 73 65 [23]
65 54 57 [22]
22 59 71 [12]
22 28 54 [2]
65 22 54 73 [12]
65 28 54 73 [52]
22 28 65 73 [42]
65 54 57 73 [22]
22 28 54 73 [4]
括号中的值表示该系列的出现。我需要根据顶部最大元素下降的数据的出现对这些数据进行排序,如下所示。
65 28 54 73 [52]
22 28 65 73 [42]
65 54 57 73 [22]
65 22 54 73 [12]
22 28 54 73 [4]
28 59 71 [122]
73 54 57 [52]
22 28 65 [26]
..
.
.
.
等等......
这是什么快速代码?
我正在尝试这个
#include<string.h>
#include <stdio.h>
int main() {
FILE *infile;
char fname[40]="resultFile1.txt";
char line[100];
int lcount=0;
if((infile = fopen(fname, "r")) == NULL) {
printf("Error Opening File.\n");
}
char *Arr[23];// need to be dynamic
while( fgets(line, sizeof(line), infile) != NULL ) {
stringArray[lcount]=line;
lcount++;
Arr[lcount]=line;
} fclose(infile);
int i;
for (i = 0; i < lcount; i++) {
printf(Arr[i]);// not able to get Arr
}
}
答案 0 :(得分:10)
我会:
qsort()
。答案 1 :(得分:2)
您可能对qsort功能感兴趣。基本上,你需要首先解析你的文件,使它在一个结构数组中,每个结构都有序列和你所谓的“出现”(键)。
然后您可以定义自己的自定义比较器功能,例如:
int compare_file_entries(void* data1, void* data2)
{
struct file_entry* entry1 = (struct file_entry*) data1;
struct file_entry* entry2 = (struct file_entry*) data2;
if ( entry1->occurence < entry2->occurence ){
return -1;
} else if ( entry2->occurence > entry2->occurence ){
return 1;
} else{
return 0;
}
}
然后,如果您有一组file_entry
个对象,比如说struct file_entry* entries
,并且您有entrycount
个这样的条目,那么您可以使用以下方式对该列表进行排序:
qsort(entries,entrycount,sizeof(struct file_entry),&compare_file_entries);
一旦对内存中的表示进行了排序,就可以将其写回文件。
答案 2 :(得分:2)
如果将问题分解为小部分(如上所述),这是最简单的。这是一般工程(无论是软件还是其他)的重要组成部分。
问题大致如下:
之后很简单!
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFFER_SIZE 100
#define MAX_NODES 1000
int count_spaces( char * s ) {
int spaces = 0;
int i;
for( i = 0; i < strlen( s ) ; i ++ ) {
if( s[ i ] == ' ' ) {
spaces++;
}
i++;
}
return spaces;
}
/* sort by number of spaces */
int sort1( char *a, char * b ) {
int spaces_a = count_spaces( a );
int spaces_b = count_spaces( b );
if( spaces_a < spaces_b )
return -1;
if( spaces_a > spaces_b )
return 1;
return 0;
}
int get_digits( char *s ) {
char buffer[ 10 ];
memset( buffer, 0, 10 );
int state = 0;
int i = 0, j = 0;
int number = 0;
for( i = 0; i < strlen( s ) ; i ++ ) {
if( state == 0 && s[ i ] == '[' ) {
state = 1;
}
if( state == 1 && s[ i ] != ']' ) {
buffer[ j ] = s[ i ];
j++;
}
if( state == 1 && s[ i ] == ']' ) {
break;
}
}
sscanf( buffer, "%d", &number );
}
/* sort by digits in brackets at the end of the line */
int sort2( char *a, char * b ) {
int a_num = get_digits( a );
int b_num = get_digits( b );
if( a_num < b_num )
return -1;
if( a_num > b_num )
return 1;
return 0;
}
int main() {
FILE *infile;
char line[ BUFFER_SIZE ];
int i = 0;
char *nodes[ MAX_NODES ];
if( (infile = fopen( "data.txt", "r" )) == NULL ) {
printf( "Error opening file\n" );
return -1;
}
while( fgets( line, BUFFER_SIZE, infile ) != NULL ) {
if( (nodes[ i ] = malloc( strlen( line ) + 1 )) == NULL ) {
printf( "Malloc failed\n" );
return -1;
}
strcpy( nodes[ i ], line );
i++;
}
// sort by # of items in a line
qsort( nodes, i, sizeof( char *), (void *)(&sort1) );
// sort by number
qsort( nodes, i, sizeof( char *), (void *)(&sort2) );
/* output results */
i--;
do {
printf( "%s", nodes[i] );
i--;
} while( i >= 0 );
}
答案 3 :(得分:1)
如果您没有严格必须在C中进行(可能是这种情况,所以这是无关紧要的),您可以使用标准的UNIX工具:
cat test | sed -r 's/.*\[(.+)\]$/\1 \0/' | sort -n -r | cut -d ' ' -f 2-
“cat test”:不是真的需要,只是把文件扔到管道上 “sed ....”:复制行开头的行李中的最后一个数字 “sort -n -r”:按相反的顺序排序第一个数字 “cut ...”:删除行开头的重复字段
从C,您可以使用system()
调用它,它会将结果抛出到stdout,但是如果您需要在程序中读取结果,则需要更多(管道..)
答案 4 :(得分:0)
Bucket按元素编号对它们进行排序(:一旦解析后读取数组长度),然后选择一个适合您对存储桶进行排序的排序,或者更好的是,使得桶的二进制搜索树的关键值是括号中的数字瞧。问题解决了。
答案 5 :(得分:0)
这是我的答案。对不起,大量的代码!
首先,一些struct
s
// contains the whole line as well as the series for ease of id
struct _Payload
{
char *line; // the line of text
int series; // the number in [ ] at the end of that line
int numElements; // the number of elements in the line
};
// a tree sorted by the series of the Payloads within
struct _PayloadTree
{
struct _Payload *payload;
struct _PayloadTree *left;
struct _PayloadTree *right;
};
// a tree sorted by the number of elements in the PayloadTree subtrees
struct _Tree
{
int numElements; // for sorting
struct _PayloadTree *payloadTree;
struct _Tree *left;
struct _Tree *right;
};
typedef struct _Payload Payload;
typedef struct _PayloadTree PayloadTree;
typedef struct _Tree Tree;
接下来,一些辅助函数:
Payload *createPayload(char *line, int series, int numElements)
{
Payload * payload = (Payload *)malloc(sizeof(Payload));
payload->line = line;
payload->series = series;
payload->numElements = numElements;
return payload;
}
PayloadTree *createPayloadTree(Payload *p)
{
PayloadTree * payloadTree = (PayloadTree *)malloc(sizeof(PayloadTree));
payloadTree->payload = p;
payloadTree->left = payloadTree->right = NULL;
return payloadTree;
}
Tree *createTree(int numElements)
{
Tree * tree = (Tree *)malloc(sizeof(Tree));
tree->numElements = numElements;
tree->payloadTree = NULL;
tree->left = tree->right = NULL;
return tree;
}
现在向树中添加内容。我们首先找到元素桶的数量,然后在适当的系列桶(PayloadTree
)
void addPayloadToPayloadTree(Payload *p, PayloadTree *payloadTree)
{
// these are sorted according to the value in 'series'
if(payloadTree == NULL) return;
PayloadTree *pt = payloadTree;
while(pt != NULL)
{
// should this happen?
if(p->series == pt->payload->series) break;
else if(p->series < pt->payload->series)
{
if(pt->left == NULL) pt->left = createPayloadTree(p);
else pt = pt->left;
}
else
{
if(pt->right == NULL) pt->right = createPayloadTree(p);
else pt = pt->right;
}
}
}
// Main way to add a line to the tree
void addPayload(Payload *p, Tree **tree)
{
if(*tree == NULL) *tree = createTree(p->numElements);
Tree *t = *tree;
while(t != NULL)
{
if(t->numElements == p->numElements) break;
else if(t->numElements > p->numElements)
{
// look left
if(t->left == NULL)
{
t->left = createTree(p->numElements);
break;
}
t = t->left;
}
else
{
// look right
if(t->right == NULL)
{
t->right = createTree(p->numElements);
break;
}
t = t->right;
}
}
// now t points to the right bucket
if(t->payloadTree == NULL) t->payloadTree = createPayloadTree(p);
addPayloadToPayloadTree(p, t->payloadTree);
}
最后是打印方法。从右到左打印:
void printPayloadTree(PayloadTree *pt)
{
if(pt == NULL) return;
printPayloadTree(pt->right);
printf("%s\n", pt->payload->line);
printPayloadTree(pt->left);
}
void printTree(Tree *t)
{
if(t == NULL) return;
printTree(t->right);
printPayloadTree(t->payloadTree);
printTree(t->left);
}
我省略了clear
函数和main
实现,因为这取决于您。这是我用来解析一条线的方法。您可以使用先前声明parseLine(theLine, &series, &numElements)
和series
numElements
int
的{{1}}来调用它。
void parseLine(char *line, int *series, int *numElements)
{
char *tok = strtok(line, " ");
int n = 0;
while(tok != NULL)
{
if(tok[0] == '[')
{
// found the series
tok[ strlen(tok) - 2 ] = '\0';
*series = atoi(tok + 1);
}
else
{
n++;
}
tok = strtok(NULL, " ");
}
*numElements = n;
}