随机数写入文件
随机100000个数,写入到文件中,读取出来从小到大排序,写入文件。
写入文件中十万个数。
C语言做法:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h> // 为了用Sleep。
int main(int argc, char* argv[])
{
srand((unsigned int)time(NULL));
clock_t StartTime, EndTime;
StartTime = clock();
FILE* fp = fopen("F:/Practice/ori", "w");
if (!fp)
{
printf("打开文件失败。");
return -1;
}
int sNum;
printf("StartTime = %ld\n", StartTime);
for (int i = 0; i < 100000; i++)
{
sNum = rand() % 100000 + 1;
fprintf(fp, "%d\n", sNum);
}
fclose(fp);
//Sleep(2000);
EndTime = clock();
printf("EndTime = %ld\n", EndTime);
double UsedTime = (double)(EndTime - StartTime) * 1.0/ CLOCKS_PER_SEC;
printf("写入十万个数耗时:%lf\n", UsedTime); // 79ms
getchar();
return 0;
}
C#做法
using System;
using System.Diagnostics;
using System.IO;
namespace 写入文件用时测试
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine("Hello World!");
Stopwatch sw = new Stopwatch();
sw.Start();
FileStream file = new FileStream(@"F:/Practice/Sharp", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter wf = new StreamWriter(file);
Random rd = new Random(Environment.TickCount);
int sjs = rd.Next(1, 10000);
for (int i = 0; i < 100000; i++)
{
sjs = rd.Next(1, 100000);
wf.WriteLine(sjs);
}
wf.Flush();
wf.Close();
file.Close();
sw.Stop();
TimeSpan ts2 = sw.Elapsed;
Console.WriteLine("span time {0}ms", ts2.TotalMilliseconds);
Console.ReadLine();// 15.7ms
}
}
}
结果发现C还不如C#快,我也不知道怎么回事。但是我想fprintf这个函数是不是不如C#的WriteLine快呀。我们把fprintf也换成C语言的写入写入行fputs。
但是需要将整数修改为string类型。用_itoa函数。试试。
for (int i = 0; i < 100000; i++)
{
sNum = rand() % 100000 + 1;
//fprintf(fp, "%d\n", sNum);
//_itoa(sNum, num, 10); // 这个无法自动换行。
sprintf(num, "%d\n", sNum);
fputs(num, fp);
}
这次是64ms。没办法了,尽力了。
试试大哥C++版本的。
#include <fstream>
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
srand(unsigned(time(0)));
int number = rand() % 100000 + 1;
DWORD start, end;
start = GetTickCount64();
ofstream ofs;
ofs.open("F:/Practice/Cplus", ios::out);
for (int i = 0; i < 100000; i++)
{
number = rand() % 100000 + 1;
ofs << number << endl;
}
ofs.close();
end = GetTickCount64();
cout << end - start << endl;
system("pause");
return 0;
}
1069ms更拉垮了。算了。咱们继续学C。
排序和排序优化
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main01(int argc, char* argv[])
{
srand((unsigned int)time(NULL));
FILE* fp = fopen("F:/Practice/ori", "w");
if (!fp)
{
printf("打开文件失败。");
perror("打开文件失败。");
return -1;
}
for (int i = 0; i < 100000; i++)
{
fprintf(fp, "%d\n", rand() % 10000 + 1);
}
fclose(fp);
//getchar();
return 0;
}
int main()
{
unsigned int start_time = time(NULL);
FILE* fp = fopen("F:/Practice/ori", "r");
if (!fp)
{
printf("打开文件失败。");
return -1;
}
int* p = (int*)malloc(sizeof(int) * 100000);
for (int i = 0; i < 100000; i++)
{
fscanf(fp, "%d\n", &p[i]);
}
//for (int i = 0; i < 100000; i++)
//{
// printf("%d\n", p[i]);
//}
//printf("排序前打印结束。\n");
//getchar();
for (int i = 0; i < 100000 - 1; i++)
{
int count = 0;
for (int j = 0; j < 100000 - i - 1; j++)
{
if (p[j] > p[j + 1])
{
int temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
fclose(fp);
fp = fopen("F:/Practice/ori", "w");
if (!fp)
{
printf("打开文件失败。");
return -1;
}
for (int i = 0; i < 100000; i++)
{
//printf("%d\n", p[i]);
fprintf(fp, "%d\n", p[i]);
}
fclose(fp);
free(p);
//printf("程序运行结束。");
unsigned int end_time = time(NULL);
printf("运行时间:%d(s)\n", end_time - start_time);
getchar();
return 0;
}
对冒泡排序的优化
对于冒泡排序,并非一定需要全数全序遍历完,只要一次排序成功,后续都是重复,可以提前终止。加入某次排序没有移动数据,那么可以认为排序终止。
for (int i = 0; i < 100000 - 1; i++)
{
int count = 0;
for (int j = 0; j < 100000 - i - 1; j++)
{
if (p[j] > p[j + 1])
{
int temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
用时22s。
另一种优化方案:
int main()
{
unsigned int start_time = time(NULL);
FILE* fp = fopen("F:/Practice/ori", "r");
if (!fp)
{
return -1;
}
int pos[10000] = { 0 };
int value = 0;
for (int i = 0; i < 100000; i++)
{
fscanf(fp, "%d\n", &value);
pos[value - 1]++;
}// 相当于完成了排序。
fclose(fp);
fp = fopen("F:/Practice/ori", "w");
if (!fp)
{
return -1;
}
int sum = 0;
// 打印输出
for (int i = 0; i < 10000; i++)
{
sum += pos[i];
for (int j = 0; j < pos[i]; j++)
{
fprintf(fp, "%d\n", i + 1);
}
}
printf("总数为:%d\n", sum);
fclose(fp);
unsigned int end_time = time(NULL);
printf("运行时间:%d(s)\n", end_time - start_time);
getchar();
return 0;
}
知道是每个数都会出现,然后统计个数。不用搬运move运算。省时省力。算法执行时间1秒。
一下子,提升了是几十倍不止。