成绩单排序(多条件)挑战
[i=s] 本帖最后由 ivor 于 2019-6-1 10:00 编辑 [/i]同时满足以下条件:
1.语文升序
2.数学降序
3.英语升序
4.化学降序
5.生物升序
[color=Red][size=5]每一行的数据不能改变,排序最小单位是行,条件是列[/size][/color]
不限制语言,数据约1w条。1秒内
样本:
[quote][color=SeaGreen]语文 数学 英语 化学 生物
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[/color]
[/quote]
抛砖引玉[code]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}[/code] [code]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;
[/code][code]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[/code]不知道理解的对不对,升降升降升,分级排序。 [i=s] 本帖最后由 xczxczxcz 于 2019-5-31 06:54 编辑 [/i]
把你的数据复制粘贴了15363多条,耗时 1.06秒。
修改了一下返回值: 现在 0.8秒。
再试试C#.
用VSCODE 写C# 编译结果15ms 输出到文本24ms。VS2019 编译 27ms 写入文本56ms。 有种使用excel的冲动 [code]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, ''));[/code] [code]$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[/code] 用bat对付一万行的数据,到1.4秒貌似下不去了:[code]@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[/code]附测试数据生成脚本[code]@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[/code] [b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=220585&ptid=52926]7#[/url] [i]CrLf[/i] [/b]
结果不正确,少一行数据 加糖,类似5楼操作。
pack - "C" An unsigned char (octet) value.
打包后的数据是字节对齐的。[code]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;
[/code] [i=s] 本帖最后由 523066680 于 2019-6-2 07:50 编辑 [/i]
PS+C Sharp 处理1W行具体时间是多少, 不懂PS 和 C Sharp
在网上找了一下 时间获取方法:[code]$start = Get-Date
# 中间代码
$end = Get-Date
Write-Host -ForegroundColor Red ('Total Runtime: ' + ($end - $start).TotalSeconds)[/code]Total Runtime: 0.1280073
perl pack 字节流方案 0.08 秒
去掉 unpack 改为按数组索引处理[code]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;
[/code]含文件输出 0.046s
2楼代码改文件输出 0.045s [b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=220611&ptid=52926]11#[/url] [i]523066680[/i] [/b]
是的,如果非常在意零点几秒速度的话,这个问题用 PowerShell 来解不合适,甚至比不过 js 脚本。
但多一种解题思路总是好的,并且 PowerShell 功能强大,速度也不算慢。关键是用它能方便地解决问题,又是系统自带,我认为这就够了。 [i=s] 本帖最后由 523066680 于 2019-6-2 07:55 编辑 [/i]
[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=220635&ptid=52926]12#[/url] [i]WHY[/i] [/b]
不在意秒,之前也未报时间。而是ivor写的 "最" 有一种钦定的意思,后面还有未发帖的人呢。ivor已经回复我了。 小白来个python版的:[code]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")[/code]python性能肯定不是最快的,用了7楼CrLf生成的测试数据1W条,运行完成时间是0.33秒左右。 有种使用数据库的冲动 [b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=220588&ptid=52926]8#[/url] [i]ivor[/i] [/b]
skip=1跳过标题行了。测试数据不包含标题行吗? [i=s] 本帖最后由 Gin_Q 于 2020-2-26 09:56 编辑 [/i]
[code]//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);
}
}[/code]结果:[code]+-----+-----+-----+-----+-----+
|原数据 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|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 |
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|小到大语文 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|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 |
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|大到小数学 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|79 |77 |70 |77 |67 |
+-----+-----+-----+-----+-----+
|79 |76 |62 |62 |77 |
+-----+-----+-----+-----+-----+
|62 |75 |65 |71 |63 |
+-----+-----+-----+-----+-----+
|74 |75 |72 |61 |61 |
+-----+-----+-----+-----+-----+
|64 |70 |74 |75 |72 |
+-----+-----+-----+-----+-----+
|74 |64 |74 |78 |69 |
+-----+-----+-----+-----+-----+
|79 |64 |72 |62 |76 |
+-----+-----+-----+-----+-----+
|71 |63 |79 |60 |70 |
+-----+-----+-----+-----+-----+
|66 |63 |77 |75 |79 |
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|小到大英语 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|79 |76 |62 |62 |77 |
+-----+-----+-----+-----+-----+
|62 |75 |65 |71 |63 |
+-----+-----+-----+-----+-----+
|79 |77 |70 |77 |67 |
+-----+-----+-----+-----+-----+
|74 |75 |72 |61 |61 |
+-----+-----+-----+-----+-----+
|79 |64 |72 |62 |76 |
+-----+-----+-----+-----+-----+
|74 |64 |74 |78 |69 |
+-----+-----+-----+-----+-----+
|64 |70 |74 |75 |72 |
+-----+-----+-----+-----+-----+
|66 |63 |77 |75 |79 |
+-----+-----+-----+-----+-----+
|71 |63 |79 |60 |70 |
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|大到小化学 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|74 |64 |74 |78 |69 |
+-----+-----+-----+-----+-----+
|79 |77 |70 |77 |67 |
+-----+-----+-----+-----+-----+
|64 |70 |74 |75 |72 |
+-----+-----+-----+-----+-----+
|66 |63 |77 |75 |79 |
+-----+-----+-----+-----+-----+
|62 |75 |65 |71 |63 |
+-----+-----+-----+-----+-----+
|79 |64 |72 |62 |76 |
+-----+-----+-----+-----+-----+
|79 |76 |62 |62 |77 |
+-----+-----+-----+-----+-----+
|74 |75 |72 |61 |61 |
+-----+-----+-----+-----+-----+
|71 |63 |79 |60 |70 |
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|小到大生物 |
+-----+-----+-----+-----+-----+
|语文 |数学 |英语 |化学 |生物 |
+-----+-----+-----+-----+-----+
|74 |75 |72 |61 |61 |
+-----+-----+-----+-----+-----+
|62 |75 |65 |71 |63 |
+-----+-----+-----+-----+-----+
|79 |77 |70 |77 |67 |
+-----+-----+-----+-----+-----+
|74 |64 |74 |78 |69 |
+-----+-----+-----+-----+-----+
|71 |63 |79 |60 |70 |
+-----+-----+-----+-----+-----+
|64 |70 |74 |75 |72 |
+-----+-----+-----+-----+-----+
|79 |64 |72 |62 |76 |
+-----+-----+-----+-----+-----+
|79 |76 |62 |62 |77 |
+-----+-----+-----+-----+-----+
|66 |63 |77 |75 |79 |
+-----+-----+-----+-----+-----+
程序耗时:0.000000[/code] [i=s] 本帖最后由 Gin_Q 于 2020-2-25 10:49 编辑 [/i]
1W行1秒内没有问题的!(CPU型号 :Intel(R) Celeron(R) CPU G1840 @ 2.80GHz)[code]+-----+-----+-----+-----+-----+
|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[/code] [i=s] 本帖最后由 Gin_Q 于 2020-2-28 19:40 编辑 [/i]
学到结构体!想到用于这个题目相当合适!!![code]#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;
}
[/code][code]语文 数学 英语 化学 生物
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
请按任意键继续. . .[/code]
页:
[1]