标题: 成绩单排序(多条件)挑战 [打印本页]
作者: ivor 时间: 2019-5-30 22:13 标题: 成绩单排序(多条件)挑战
本帖最后由 ivor 于 2019-6-1 10:00 编辑
同时满足以下条件:
1.语文升序
2.数学降序
3.英语升序
4.化学降序
5.生物升序
每一行的数据不能改变,排序最小单位是行,条件是列
不限制语言,数据约1w条。1秒内
样本:
语文 数学 英语 化学 生物
79 77 70 77 67
64 70 74 75 72
79 64 72 62 76
62 75 65 71 63
79 76 62 62 77
66 63 77 75 79
74 75 72 61 61
71 63 79 60 70
74 64 74 78 69
抛砖引玉- GC "1.txt" | select @{name='语文'; expression={$_.split(" ")[0]}},
- @{name='数学'; expression={$_.split(" ")[1]}},
- @{name='英语'; expression={$_.split(" ")[2]}},
- @{name='化学'; expression={$_.split(" ")[3]}},
- @{name='生物'; expression={$_.split(" ")[4]}} | `
- Sort-Object -Property @{Expression = {$_.语文}; Ascending = $true},
- @{Expression = {$_.数学}; Ascending = $false},
- @{Expression = {$_.英语}; Ascending = $true},
- @{Expression = {$_.化学}; Ascending = $false},
- @{Expression = {$_.生物}; Ascending = $true}
复制代码
作者: 523066680 时间: 2019-5-30 22:36
- use Encode;
- use File::Slurp;
- STDOUT->autoflush(1);
-
- my @lines = read_file("src.txt");
- my $head = shift @lines;
-
- my @mat = map { s/\r?\n$//; [split " ", $_]; } @lines;
-
- @mat = sort {
- $a->[0] <=> $b->[0] ||
- $b->[1] <=> $a->[1] ||
- $a->[2] <=> $b->[2] ||
- $b->[3] <=> $a->[3] ||
- $a->[4] <=> $b->[4]
- } @mat;
-
- grep { printf "%s\n", join(",", @$_); } @mat;
复制代码
- 62,75,65,71,63
- 64,70,74,75,72
- 66,63,77,75,79
- 71,63,79,60,70
- 74,75,72,61,61
- 74,64,74,78,69
- 79,77,70,77,67
- 79,76,62,62,77
- 79,64,72,62,76
复制代码
不知道理解的对不对,升降升降升,分级排序。
作者: xczxczxcz 时间: 2019-5-30 22:50
本帖最后由 xczxczxcz 于 2019-5-31 06:54 编辑
把你的数据复制粘贴了15363多条,耗时 1.06秒。
修改了一下返回值: 现在 0.8秒。
再试试C#.
用VSCODE 写C# 编译结果15ms 输出到文本24ms。VS2019 编译 27ms 写入文本56ms。
作者: 老刘1号 时间: 2019-5-31 12:22
有种使用excel的冲动
作者: WHY 时间: 2019-6-1 00:42
- var fso = new ActiveXObject('Scripting.FileSystemObject');
- var txt = fso.OpenTextFile('1.txt', 1).ReadAll();
-
- var arr = txt.replace(/^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)(?:\r\n|$)/mg,
- function(s0, s1, s2, s3, s4, s5){
- return 100 + 1*s1 + '' + (200 - s2) + '' + (100 + 1*s3) + '' + (200 - s4) + '' + (100 + 1*s5) + ' ' + s0;
- }
- ).split(/\r\n/).sort();
-
- fso.OpenTextFile('2.txt', 2, true).Write(arr.join('\r\n').replace(/^\d+ /mg, ''));
复制代码
作者: WHY 时间: 2019-6-1 00:46
- $Code = @"
- using System;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Collections.Generic;
-
- public static class Program {
- public static IEnumerable<string> Run(string[] lines) {
- var query = from line in lines
- let m = Regex.Match(line, @"^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$")
- where m.Success == true
- orderby int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value) descending, int.Parse(m.Groups[3].Value),
- int.Parse(m.Groups[4].Value) descending, int.Parse(m.Groups[5].Value)
- select line;
- return query;
- }
- }
- "@;
- Add-Type -TypeDefinition $Code;
- $arr = [IO.File]::ReadAllLines('1.txt');
- [IO.File]::WriteAllLines('2.txt', [Program]::Run($arr));
- pause
复制代码
作者: CrLf 时间: 2019-6-1 01:21
用bat对付一万行的数据,到1.4秒貌似下不去了:- @echo off & setlocal enabledelayedexpansion
-
- echo %time% - 开始
-
- for /l %%a in (0 1 99) do (
- set /a B=10%%a,L=200-%%a
- set B%%a=!B:~-2!
- set L%%a=!L:~-2!
- )
-
- set B100=xx
- set L100=--
-
- echo %time% - 构建映射表
-
- (for /f "skip=1 tokens=1-5" %%a in (test.txt) do (
- echo !B%%a!!L%%b!!B%%c!!L%%d!!B%%e! %%a %%b %%c %%d %%e
- ))>tmp.txt
-
- echo %time% - 输出临时文件
-
- (echo 语文 数学 英语 化学 生物
- for /f "tokens=1*" %%a in ('sort tmp.txt') do echo %%b
- )>out.txt
-
- echo %time% - 结束
-
- pause & exit /b
复制代码
附测试数据生成脚本- @echo off & setlocal enabledelayedexpansion
- (echo 语文 数学 英语 化学 生物
- for /l %%a in (1 1 10000) do (
- set /a R1=!random!%%101,R2=!random!%%101,R3=!random!%%101,R4=!random!%%101,R5=!random!%%101
- echo !R1! !R2! !R3! !R4! !R5!
- ))>test.txt
- pause
复制代码
作者: ivor 时间: 2019-6-1 08:13
回复 7# CrLf
结果不正确,少一行数据
作者: 523066680 时间: 2019-6-1 09:35
加糖,类似5楼操作。
pack - "C" An unsigned char (octet) value.
打包后的数据是字节对齐的。- use File::Slurp;
- STDOUT->autoflush(1);
- my @lines = read_file("src.txt");
- my $head = shift @lines;
-
- grep {
- my $it = 0;
- printf "%s\n", join(",", map { $it++%2 ? 100-$_ : $_ } unpack("C*", $_));
- } sort map {
- my $it = 0;
- s/\r?\n$//;
- pack("C*", map { $it++%2 ? 100-$_ : $_ } split " ", $_);
- } @lines;
复制代码
作者: 523066680 时间: 2019-6-1 18:28
本帖最后由 523066680 于 2019-6-2 07:50 编辑
PS+C Sharp 处理1W行具体时间是多少, 不懂PS 和 C Sharp
在网上找了一下 时间获取方法:- $start = Get-Date
- # 中间代码
- $end = Get-Date
- Write-Host -ForegroundColor Red ('Total Runtime: ' + ($end - $start).TotalSeconds)
复制代码
Total Runtime: 0.1280073
perl pack 字节流方案 0.08 秒
去掉 unpack 改为按数组索引处理- use File::Slurp;
- use Time::HiRes qw/time/;
- my $ta = time();
- my @lines = read_file("test.txt");
- my $head = shift @lines;
- my $buff = "";
-
- my @dupl = map {
- my $it = 0;
- s/\r?\n$//;
- pack("C*", map { $it++%2 ? 100-$_ : $_ } split " ", $_);
- } @lines;
-
- my @idx = sort { $dupl[$a] cmp $dupl[$b] } (0..$#dupl);
- grep { $buff .= $lines[$_] ."\r\n" } @idx;
- write_file("pl_out.txt", {binmode=>"raw"}, $buff);
- printf "%.3f\n", time() - $ta;
复制代码
含文件输出 0.046s
2楼代码改文件输出 0.045s
作者: WHY 时间: 2019-6-1 22:47
回复 11# 523066680
是的,如果非常在意零点几秒速度的话,这个问题用 PowerShell 来解不合适,甚至比不过 js 脚本。
但多一种解题思路总是好的,并且 PowerShell 功能强大,速度也不算慢。关键是用它能方便地解决问题,又是系统自带,我认为这就够了。
作者: 523066680 时间: 2019-6-2 07:54
本帖最后由 523066680 于 2019-6-2 07:55 编辑
回复 12# WHY
不在意秒,之前也未报时间。而是ivor写的 "最" 有一种钦定的意思,后面还有未发帖的人呢。ivor已经回复我了。
作者: cfwyy77_bat 时间: 2019-6-2 11:15
小白来个python版的:- file = "test.txt"
- result = "res.txt"
- with open(file,"r",encoding="utf8") as f:
- head = f.readline() #读第一行头
- gen = (tuple(int(x) for x in line.split()) for line in f)
- res = sorted(gen,key=lambda x:(x[0],-x[1],x[2],-x[3],x[4])) #多条件排序,取负值按降序
-
- with open(result,"w") as f:
- f.write(head) #写第一行头
- for i in res:
- f.write(" ".join(str(x) for x in i)) #拼接成字符串写入
- f.write("\n")
复制代码
python性能肯定不是最快的,用了7楼CrLf生成的测试数据1W条,运行完成时间是0.33秒左右。
作者: Batcher 时间: 2019-6-2 12:27
有种使用数据库的冲动
作者: CrLf 时间: 2019-6-2 15:03
回复 8# ivor
skip=1跳过标题行了。测试数据不包含标题行吗?
作者: Gin_Q 时间: 2020-2-24 18:53
本帖最后由 Gin_Q 于 2020-2-26 09:56 编辑
- //Dev-C++ 5.11
- //排序算法用的是选择排序
- //by Gin
-
- #include <time.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define LINE_SIZE 100 //行存储大小
-
-
- FILE *fp(char *,const char *);
- int check_width(FILE *fp);
- int check_high(FILE *fp);
-
- int main(int argc,char *argv[])
- {
- clock_t start_t,end_t; //计时
- double time_sum; //储存时间
- start_t=clock(); //开始计时
-
- FILE *a_txt=fp(argv[1],"r");
- FILE *b_txt=fp(argv[2],"w");
-
- int width=0,high=0;
- width=check_width(a_txt);
- high=check_high(a_txt);
-
- void anay(char *,char *,int linesize,int width); //把二维素组做一维数组传递
- void init(char *,int *,int linesize,int width); //把二维素组做一维数组传递
- void sort_min_max(int *p,int high,int width,int n); //小到大
- void sort_max_min(int *p,int high,int width,int n); //大到小
- void res_print(FILE *fp,int *p,int high,int width,char *p_kemu,char *kemu,char *way,char *form,char *form_1,char *form_2); //打印结果
-
- char mu[LINE_SIZE]="0"; //储存第一行数据
- char temp_1[high][width]={"0"}; //存储分割好的数据
- char temp[LINE_SIZE]="0"; //存储一行数据
- int arr[high][width]={0}; //存储最终数组
- int (*p_arr)[width]=arr;
- char kemu[5][7]={"0"};
- char *p_kemu=kemu[0];
-
- char original[40]="原数据";
- char min_m[7]="小到大";
- char max_m[7]="大到小";
- char form[8]="+-----+";
- char form_1[8]="-----+";
- char form_2[2]="|";
- char spk[2]="\0";
-
- rewind(a_txt);
- fgets(mu,LINE_SIZE,a_txt);
- anay(mu,(char*)kemu,7,width);
-
- int i;
- for (i=0;fgets(temp,LINE_SIZE,a_txt)!=NULL;i++)
- {
- anay(temp,temp_1[0],width,width); //将数据分割成二维字符串
- init(temp_1[0],arr[i],width,width); //将二维字符串赋值给二维数组
- }
-
- res_print(b_txt,(int *)arr,high,width,p_kemu,spk,original,form,form_1,form_2);
- fputc('\n',b_txt);
-
- int mark=0; //0代表升序,1代表降序
-
- for (i=0;i<width;i++)
- {
- if (mark==0)
- {
- sort_min_max((int *)arr,high,width,i);
- mark=1;
- res_print(b_txt,(int *)arr,high,width,p_kemu,kemu[i],min_m,form,form_1,form_2);
- }
- else if (mark==1)
- {
- sort_max_min((int *)arr,high,width,i);
- mark=0;
- res_print(b_txt,(int *)arr,high,width,p_kemu,kemu[i],max_m,form,form_1,form_2);
- }
- if (i<(high-1)) fputs("\n",b_txt);
- }
- end_t=clock();
- time_sum=(double)(end_t-start_t)/CLOCKS_PER_SEC;
- fprintf(b_txt,"程序耗时:%f",time_sum);
- fclose(a_txt);
- fclose(b_txt);
- return 0;
-
-
- }
- FILE *fp(char *p,const char *mode)
- {
- FILE *pp;
- if ((pp= fopen(p,mode))==NULL)
- {
- printf("open fail! %s",p);
- getchar();
- exit (0);
- }
- return pp;
- }
- //检查数据
- int check_width(FILE *fp)
- {
- rewind(fp);
- char delims='0';
- int w=1;
- for (;(delims=fgetc(fp))!='\n';)
- {
- if (delims==' ') w++;
- }
- return w;
- }
- int check_high(FILE *fp)
- {
- rewind(fp);
- int h=0;
- char arr[LINE_SIZE];
- for (;fgets(arr,LINE_SIZE,fp)!=NULL;h++);
- return h-1; //去掉第一行不算
- }
- void anay(char *p,char *t,int linesize, int width)
- {
- int i,j=0,k=0; //j第二维,k第一维
- for (i=0;*(p+i)!='\0';i++)
- {
- if (*(p+i)!=' ' && *(p+i)!='\n')
- {
- *(t+j*linesize+k)=*(p+i);
- k++;
- }
- else
- {
- *(t+j*linesize+k)='\0';
- j++,k=0;
- }
- }
- }
- void init(char *p,int *p1,int linesize,int width)
- {
- int i;
- for (i=0;i<width;i++)
- {
- *(p1+i)=atoi(p+i*linesize);
- }
- }
- void sort_min_max(int *p,int high,int width,int n)
- {
- int i,k,l,temp=0;
- for (i=0;i<high-1;i++)
- {
- for (k=i+1;k<high;k++)
- {
- if (*(p+k*width+n)<*(p+i*width+n))
- {
- for (l=0;l<width;l++)
- {
- temp=*(p+k*width+l);
- *(p+k*width+l)=*(p+i*width+l);
- *(p+i*width+l)=temp;
- }
- }
- }
- }
- }
- void sort_max_min(int *p,int high,int width,int n)
- {
- int i,k,l,temp=0;
- for (i=0;i<high-1;i++)
- {
- for (k=i+1;k<high;k++)
- {
- if (*(p+k*width+n)>*(p+i*width+n))
- {
- for (l=0;l<width;l++)
- {
- temp=*(p+k*width+l);
- *(p+k*width+l)=*(p+i*width+l);
- *(p+i*width+l)=temp;
- }
- }
- }
- }
- }
- void res_print(FILE *fp,int *p,int high,int width,char *p_kemu,char *kemu,char *way,char *form,char *form_1,char *form_2)
- {
- fprintf(fp,"%s%s%s%s%s\n",form,form_1,form_1,form_1,form_1);
- fprintf(fp,"%s%6s%-23s%s\n",form_2,way,kemu,form_2);
- fprintf(fp,"%s%s%s%s%s\n",form,form_1,form_1,form_1,form_1);
- for (int i=0;i<width;i++) fprintf(fp,"%s%-5s",form_2,(p_kemu+i*7));
- fprintf(fp,"%s\n%s%s%s%s%s\n",form_2,form,form_1,form_1,form_1,form_1);
- int i,j;
- for (i=0;i<high;i++)
- {
- for (j=0;j<width;j++)
- {
- fprintf(fp,"%s%-5d",form_2,*(p+i*width+j));
- }
- fprintf(fp,"%s\n",form_2);
- fprintf(fp,"%s%s%s%s%s",form,form_1,form_1,form_1,form_1);
- fputc('\n',fp);
- }
- }
复制代码
结果:复制代码
作者: Gin_Q 时间: 2020-2-24 19:53
本帖最后由 Gin_Q 于 2020-2-25 10:49 编辑
1W行1秒内没有问题的!(CPU型号 :Intel(R) Celeron(R) CPU G1840 @ 2.80GHz)- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
- |66 |63 |77 |75 |79 |
- +-----+-----+-----+-----+-----+
-
- 程序耗时:0.916000
复制代码
作者: Gin_Q 时间: 2020-2-28 11:43
本帖最后由 Gin_Q 于 2020-2-28 19:40 编辑
学到结构体!想到用于这个题目相当合适!!!- #include <stdio.h>
- struct Student
- {
- int nu_1;
- int nu_2;
- int nu_3;
- int nu_4;
- int nu_5;
- };
- int main(void)
- {
- struct Student arr[9]={{79,77,70,77,67},{64,70,74,75,72},{79,64,72,62,76},{62,75,65,71,63},
- {79,76,62,62,77},{66,63,77,75,79},{74,75,72,61,61},{71,63,79,60,70},{74,64,74,78,69}};
- struct Student temp;
- const int n=9;
- int i,j;
- for (i=0;i<n-1;i++)
- {
- for (j=i+1;j<n;j++)
- {
- if (arr[i].nu_1>arr[j].nu_1)
- {
- temp=arr[i];arr[i]=arr[j];arr[j]=temp;
- }
- }
- }
- printf("语文 数学 英语 化学 生物\n");
- for (i=0;i<n;i++) printf("%-5d%-5d%-5d%-5d%-5d\n",arr[i].nu_1,arr[i].nu_2,arr[i].nu_3,arr[i].nu_4,arr[i].nu_5);
- return 0;
- }
复制代码
- 语文 数学 英语 化学 生物
- 62 75 65 71 63
- 64 70 74 75 72
- 66 63 77 75 79
- 71 63 79 60 70
- 74 75 72 61 61
- 74 64 74 78 69
- 79 77 70 77 67
- 79 76 62 62 77
- 79 64 72 62 76
-
- --------------------------------
- Process exited after 0.01317 seconds with return value 0
- 请按任意键继续. . .
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |