帮我看看这个程序主要是哪里耗时谢谢了。

crescent_star 2009-08-19 11:45:27
最大输入数目为100000,限时为2s。我总是超时。


#include <iostream>
#include <string>

using namespace std;

typedef struct
{
int Elem[100002];
int length;
}COutPut;

int Partition(COutPut &L, int low, int high)
{
// 交换排序表L中字表Elem[low...high]的记录,枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它
L.Elem[0] = L.Elem[low]; // 用子表的第一个记录作枢轴记录
int pivokey = L.Elem[low];
while (low < high)
{
// 从表的两端交替地向中间扫描
while (low < high && L.Elem[high] >= pivokey)
{
--high;
}
L.Elem[low] = L.Elem[high]; // 将比枢轴记录小的记录移到低端
while (low < high && L.Elem[low] <= pivokey)
{
++low;
}
L.Elem[high] = L.Elem[low]; // 将比枢轴记录大的记录移到高端
}
L.Elem[low] = L.Elem[0]; // 枢轴记录到位
return low;
}

void QSort(COutPut &L, int low, int high)
{
// 对顺序表L中的子序列L.Elem[low...high]作快速排序
int pivotloc;
if (low < high)
{
// 长度大于1
pivotloc = Partition(L, low, high); // 将L.Elem[low...high]一分为二
QSort(L, low, pivotloc - 1); // 对低子表递归排序,pivotloc是枢轴位置
QSort(L, pivotloc + 1, high); //对高字表递归排序
}
}

int main()
{
// ASCII码,0~9对应48~57,A~P对应65~80,R~Y对应82~89,-为45
// 这道题的数值判断感觉可以用ASCII码会^^高级一点- -。
// 第一遍的思路:输入一个就去前面搜。
// 超时,肯定的。

// 新的思路:插入时不判断重复,全部输入完成后,进行快排,然后输出
// 第二遍时输出的时候超时了,因为我是把int通过strstream转成了string然后补0加-输出,很耗时

int m_Count;

cin >> m_Count;

// 大于100000报错
if (m_Count > 100000)
{
cout << "Input is too large!" << endl;
system("pause");
return 0;
}
else if (m_Count < 1)
{
cout << "Input is too small!" << endl;
system("pause");
return 0;
}

// 用来控制输入的字符串数量等于m_Count的临时变量
int m_CountTemp = 0;

// 用来保存输入的字符串,处理过后的,因为是一个七位数,int是能存下的
COutPut m_StrDealed_ToInt;

// 用来接收每一次输入的字符串然后处理的字符串变量
string m_StrInput;

// 循环str的临时变量
int m_StrCycle_Temp;

// 用来计算每个字符串中的字符除掉-后是否为7个
int m_NumCount;

// 找到'-'位置的临时变量
int m_Pos = 0;

// 循环m_StrDealed_ToInt的临时变量
int m_IntCycle_Temp;

// 用来存储接收到的字符串所变成的Int的临时变量
int m_StrDealed_ToInt_Temp;

// 用来标识真正加入到COutPut里的数据的数目的临时变量
int m_ValueCount_Temp = 0;

// 输出时重复的数据的计数
int m_RepeatCount = 1;

// 用来标识是否有重复数据
bool b_RepeatExist;

// 初始化,0位作排序标志位,length最开始置0
m_StrDealed_ToInt.length = 0;
m_StrDealed_ToInt.Elem[0] = 0;

// 输入
while ((m_CountTemp < m_Count) && (cin >> m_StrInput))
{
// 去掉所有的'-'
m_Pos = m_StrInput.find('-');

while (m_Pos != -1)
{
m_StrInput = m_StrInput.substr(0, m_Pos) + m_StrInput.substr(m_Pos + 1, m_StrInput.size());
m_Pos = m_StrInput.find('-');
}

m_NumCount = 0;

// 转换并计数
for (m_StrCycle_Temp = 0; m_StrCycle_Temp < m_StrInput.size(); m_StrCycle_Temp++)
{
if ( (m_StrInput[m_StrCycle_Temp] == 'A') || (m_StrInput[m_StrCycle_Temp] == 'B') || (m_StrInput[m_StrCycle_Temp] == 'C'))
{
m_StrInput[m_StrCycle_Temp] = '2';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'D') || (m_StrInput[m_StrCycle_Temp] == 'E') || (m_StrInput[m_StrCycle_Temp] == 'F'))
{
m_StrInput[m_StrCycle_Temp] = '3';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'G') || (m_StrInput[m_StrCycle_Temp] == 'H') || (m_StrInput[m_StrCycle_Temp] == 'I'))
{
m_StrInput[m_StrCycle_Temp] = '4';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'J') || (m_StrInput[m_StrCycle_Temp] == 'K') || (m_StrInput[m_StrCycle_Temp] == 'L'))
{
m_StrInput[m_StrCycle_Temp] = '5';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'M') || (m_StrInput[m_StrCycle_Temp] == 'N') || (m_StrInput[m_StrCycle_Temp] == 'O'))
{
m_StrInput[m_StrCycle_Temp] = '6';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'P') || (m_StrInput[m_StrCycle_Temp] == 'R') || (m_StrInput[m_StrCycle_Temp] == 'S'))
{
m_StrInput[m_StrCycle_Temp] = '7';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'T') || (m_StrInput[m_StrCycle_Temp] == 'U') || (m_StrInput[m_StrCycle_Temp] == 'V'))
{
m_StrInput[m_StrCycle_Temp] = '8';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'W') || (m_StrInput[m_StrCycle_Temp] == 'X') || (m_StrInput[m_StrCycle_Temp] == 'Y'))
{
m_StrInput[m_StrCycle_Temp] = '9';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] >= '0') && (m_StrInput[m_StrCycle_Temp] <= '9'))
{
// 0~9
m_NumCount++;
}
else
{
cout << "Input is not in (A~P && 0~9 && -). No Accepted!" << endl;
system("pause");
return 0;
}
}

// 如果长度不为7,不接受
if (m_NumCount != 7)
{
cout << "The num of the characters (not inclued '-') in string is not 7. No Accepted!" << endl;
system("pause");
return 0;
}

// 将该字符串转换为Int
m_StrDealed_ToInt_Temp = atoi(m_StrInput.c_str());

m_StrDealed_ToInt.Elem[m_CountTemp+1] = m_StrDealed_ToInt_Temp;
m_StrDealed_ToInt.length++;

// 这是用于计算输入的字符串个数的
m_CountTemp++;
}

// 快速排序
QSort(m_StrDealed_ToInt, 1, m_StrDealed_ToInt.length);

// 输出
b_RepeatExist = false;

for (m_IntCycle_Temp = 1; m_IntCycle_Temp <= m_StrDealed_ToInt.length; m_IntCycle_Temp++)
{
if (m_StrDealed_ToInt.Elem[m_IntCycle_Temp+1] != m_StrDealed_ToInt.Elem[m_IntCycle_Temp])
{
// 有输出了就改为true
if (m_RepeatCount != 1)
{
if (!b_RepeatExist)
{
b_RepeatExist = true;
}

// 输出
printf("%.3d-%.4d %d\n", m_StrDealed_ToInt.Elem[m_IntCycle_Temp]/10000, m_StrDealed_ToInt.Elem[m_IntCycle_Temp]%10000, m_RepeatCount);
}

m_RepeatCount = 1;
}
else
{
m_RepeatCount++;
}
}

if (!b_RepeatExist)
{
cout << "No duplicates." << endl;
}

system("pause");

return 1;
}

...全文
114 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyram 2009-08-19
  • 打赏
  • 举报
回复
一些省时间的建议:
acm题不要去验证输入,这个是有保证的。
快排改用随机选取标志,才能达到平均O(nlogn)。
输入输出如果该用c中的方式会更快。scanf,printf
crescent_star 2009-08-19
  • 打赏
  • 举报
回复
没有n*n吧?

最耗时的应该是快速排序,理论上应该是o(nlnn)。
当然快排的最差是n*n,但平均是是o(nlnn)啊。
Paradin 2009-08-19
  • 打赏
  • 举报
回复
你复杂度是多少
n*n肯定超时的
crescent_star 2009-08-19
  • 打赏
  • 举报
回复
输入输出例子:

Sample Input

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3

输入:
2
---3333--3-3-3--
-3333333

输出:
333-3333 2

输入:
4
0000000
0010001
0000000
0010001

输出:
000-0000 2
001-0001 2
whg01 2009-08-19
  • 打赏
  • 举报
回复
1. 打出各段代码消耗的时间,看看哪里比预想的慢。
2. 看看VC里带的快速排序算法,此外再看看《编程珠玑》中关于快速排序的内容。
zhangxfeng112 2009-08-19
  • 打赏
  • 举报
回复
最多用一个判断,
要是好好设计一下,的话一个判断都不用.
m_StrInput[m_StrCycle_Temp] = ***;
m_NumCount++;

***自己用位操作去设计一个
zhangxfeng112 2009-08-19
  • 打赏
  • 举报
回复

for (m_StrCycle_Temp = 0; m_StrCycle_Temp < m_StrInput.size(); m_StrCycle_Temp++)
{
if ( (m_StrInput[m_StrCycle_Temp] == 'A') || (m_StrInput[m_StrCycle_Temp] == 'B') || (m_StrInput[m_StrCycle_Temp] == 'C'))
{
m_StrInput[m_StrCycle_Temp] = '2';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'D') || (m_StrInput[m_StrCycle_Temp] == 'E') || (m_StrInput[m_StrCycle_Temp] == 'F'))
{
m_StrInput[m_StrCycle_Temp] = '3';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'G') || (m_StrInput[m_StrCycle_Temp] == 'H') || (m_StrInput[m_StrCycle_Temp] == 'I'))
{
m_StrInput[m_StrCycle_Temp] = '4';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'J') || (m_StrInput[m_StrCycle_Temp] == 'K') || (m_StrInput[m_StrCycle_Temp] == 'L'))
{
m_StrInput[m_StrCycle_Temp] = '5';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'M') || (m_StrInput[m_StrCycle_Temp] == 'N') || (m_StrInput[m_StrCycle_Temp] == 'O'))
{
m_StrInput[m_StrCycle_Temp] = '6';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'P') || (m_StrInput[m_StrCycle_Temp] == 'R') || (m_StrInput[m_StrCycle_Temp] == 'S'))
{
m_StrInput[m_StrCycle_Temp] = '7';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'T') || (m_StrInput[m_StrCycle_Temp] == 'U') || (m_StrInput[m_StrCycle_Temp] == 'V'))
{
m_StrInput[m_StrCycle_Temp] = '8';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'W') || (m_StrInput[m_StrCycle_Temp] == 'X') || (m_StrInput[m_StrCycle_Temp] == 'Y'))
{
m_StrInput[m_StrCycle_Temp] = '9';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] >= '0') && (m_StrInput[m_StrCycle_Temp] <= '9'))
{
// 0~9
m_NumCount++;
}
else
{
cout << "Input is not in (A~P && 0~9 && -). No Accepted!" << endl;
system("pause");
return 0;
}


这里判断的case太多了,用位操作可以2,3行代码搞定.
ztenv 版主 2009-08-19
  • 打赏
  • 举报
回复
什么破程序结构,,,,,好好优化一下结构再说;
crescent_star 2009-08-19
  • 打赏
  • 举报
回复
解决了。

很无语。自己写的快排没有自带的qsort快,而且慢的不是一点点。。。
crescent_star 2009-08-19
  • 打赏
  • 举报
回复
谢谢。程序里没有两重循环。

另,修改了用随机数的快速排序。仍旧超时,烦闷依旧- -。


#include <iostream>
#include <string>
#include <ctime>

using namespace std;

typedef struct
{
int Elem[100002];
int length;
}COutPut;

double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}

int Partition(COutPut &L, int low, int high)
{
// 交换排序表L中字表Elem[low...high]的记录,枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它

srand(unsigned(time(0)));

int m_Random = random(low,high);

L.Elem[0] = L.Elem[m_Random]; // 用随机出的记录作枢轴记录
int pivokey = L.Elem[m_Random];

int temp;
temp = L.Elem[m_Random];
L.Elem[m_Random] = L.Elem[low];
L.Elem[low] = L.Elem[m_Random];

while (low < high)
{
// 从表的两端交替地向中间扫描
while (low < high && L.Elem[high] >= pivokey)
{
--high;
}
L.Elem[low] = L.Elem[high]; // 将比枢轴记录小的记录移到低端
while (low < high && L.Elem[low] <= pivokey)
{
++low;
}
L.Elem[high] = L.Elem[low]; // 将比枢轴记录大的记录移到高端
}
L.Elem[low] = L.Elem[0]; // 枢轴记录到位
return low;
}

void QSort(COutPut &L, int low, int high)
{
// 对顺序表L中的子序列L.Elem[low...high]作快速排序
int pivotloc;
if (low < high)
{
// 长度大于1
pivotloc = Partition(L, low, high); // 将L.Elem[low...high]一分为二
QSort(L, low, pivotloc - 1); // 对低子表递归排序,pivotloc是枢轴位置
QSort(L, pivotloc + 1, high); //对高字表递归排序
}
}

int main()
{
int m_Count;

cin >> m_Count;

// 用来控制输入的字符串数量等于m_Count的临时变量
int m_CountTemp = 0;

// 用来保存输入的字符串,处理过后的,因为是一个七位数,int是能存下的
COutPut m_StrDealed_ToInt;

// 用来接收每一次输入的字符串然后处理的字符串变量
string m_StrInput;

// 循环str的临时变量
int m_StrCycle_Temp;

// 用来计算每个字符串中的字符除掉-后是否为7个
int m_NumCount;

// 找到'-'位置的临时变量
int m_Pos = 0;

// 循环m_StrDealed_ToInt的临时变量
int m_IntCycle_Temp;

// 用来存储接收到的字符串所变成的Int的临时变量
int m_StrDealed_ToInt_Temp;

// 用来标识真正加入到COutPut里的数据的数目的临时变量
int m_ValueCount_Temp = 0;

// 输出时重复的数据的计数
int m_RepeatCount = 1;

// 用来标识是否有重复数据
bool b_RepeatExist;

// 初始化,0位作排序标志位,length最开始置0
m_StrDealed_ToInt.length = 0;
m_StrDealed_ToInt.Elem[0] = 0;

// 输入
while ((m_CountTemp < m_Count) && (cin >> m_StrInput))
{
// 去掉所有的'-'
m_Pos = m_StrInput.find('-');

while (m_Pos != -1)
{
m_StrInput = m_StrInput.substr(0, m_Pos) + m_StrInput.substr(m_Pos + 1, m_StrInput.size());
m_Pos = m_StrInput.find('-');
}

m_NumCount = 0;

// 转换并计数
for (m_StrCycle_Temp = 0; m_StrCycle_Temp < m_StrInput.size(); m_StrCycle_Temp++)
{
if ( (m_StrInput[m_StrCycle_Temp] == 'A') || (m_StrInput[m_StrCycle_Temp] == 'B') || (m_StrInput[m_StrCycle_Temp] == 'C'))
{
m_StrInput[m_StrCycle_Temp] = '2';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'D') || (m_StrInput[m_StrCycle_Temp] == 'E') || (m_StrInput[m_StrCycle_Temp] == 'F'))
{
m_StrInput[m_StrCycle_Temp] = '3';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'G') || (m_StrInput[m_StrCycle_Temp] == 'H') || (m_StrInput[m_StrCycle_Temp] == 'I'))
{
m_StrInput[m_StrCycle_Temp] = '4';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'J') || (m_StrInput[m_StrCycle_Temp] == 'K') || (m_StrInput[m_StrCycle_Temp] == 'L'))
{
m_StrInput[m_StrCycle_Temp] = '5';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'M') || (m_StrInput[m_StrCycle_Temp] == 'N') || (m_StrInput[m_StrCycle_Temp] == 'O'))
{
m_StrInput[m_StrCycle_Temp] = '6';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'P') || (m_StrInput[m_StrCycle_Temp] == 'R') || (m_StrInput[m_StrCycle_Temp] == 'S'))
{
m_StrInput[m_StrCycle_Temp] = '7';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'T') || (m_StrInput[m_StrCycle_Temp] == 'U') || (m_StrInput[m_StrCycle_Temp] == 'V'))
{
m_StrInput[m_StrCycle_Temp] = '8';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] == 'W') || (m_StrInput[m_StrCycle_Temp] == 'X') || (m_StrInput[m_StrCycle_Temp] == 'Y'))
{
m_StrInput[m_StrCycle_Temp] = '9';
m_NumCount++;
}
else if ( (m_StrInput[m_StrCycle_Temp] >= '0') && (m_StrInput[m_StrCycle_Temp] <= '9'))
{
// 0~9
m_NumCount++;
}
}

// 将该字符串转换为Int
m_StrDealed_ToInt_Temp = atoi(m_StrInput.c_str());

m_StrDealed_ToInt.Elem[m_CountTemp+1] = m_StrDealed_ToInt_Temp;
m_StrDealed_ToInt.length++;

// 这是用于计算输入的字符串个数的
m_CountTemp++;
}

// 快速排序
QSort(m_StrDealed_ToInt, 1, m_StrDealed_ToInt.length);

// 输出
b_RepeatExist = false;

for (m_IntCycle_Temp = 1; m_IntCycle_Temp <= m_StrDealed_ToInt.length; m_IntCycle_Temp++)
{
if (m_StrDealed_ToInt.Elem[m_IntCycle_Temp+1] != m_StrDealed_ToInt.Elem[m_IntCycle_Temp])
{
// 有输出了就改为true
if (m_RepeatCount != 1)
{
if (!b_RepeatExist)
{
b_RepeatExist = true;
}

// 输出
printf("%.3d-%.4d %d\n", m_StrDealed_ToInt.Elem[m_IntCycle_Temp]/10000, m_StrDealed_ToInt.Elem[m_IntCycle_Temp]%10000, m_RepeatCount);
}

m_RepeatCount = 1;
}
else
{
m_RepeatCount++;
}
}

if (!b_RepeatExist)
{
cout << "No duplicates." << endl;
}

system("pause");

return 1;
}
科技完美生活 2009-08-19
  • 打赏
  • 举报
回复
请重点关注两层循环处

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧