今偶然在论坛上遇到一面试题,虽然简单,但在各种解法中还是有很多值得借鉴的地方。本文目的在于锻炼思维,汲取一些好的思想。总结一下就是,首先根据问题设计数学模型,从而找到合适的算法;在代码书写方面要学会活用:布尔运算的返回值、||,&&逻辑运算、条件表达式、%求余运算、/除法运算等,从而可以使代码更加简洁。(wcdj 2010-3-10)
题目如下:
只允许使用一个循环,先输出1至10内的奇数,然后输出其中的偶数,结果应该是这样的:
1
3
5
7
9
2
4
6
8
来源:http://topic.csdn.net/u/20081114/18/ad521288-2901-4868-8430-77a0e01ae746.html?27095
第一种想法
:利用循环直接先输出奇数再输出偶数。
关键点:用i控制循环次数,用j计算所要求的数字。
第二种想法
:对第一种想法的改进,利用循环直接先输出奇数再输出偶数。
关键点:用i计算所要求的数字,构造一个数学中的函数:
f(x)=2x-1, x<=5
f(x)=2(x-5), x>5
或者:
return 0;
}
上述方法更简洁点的方式为:(利用||和&&运算符的“短路原理”)
类似的思路,将遍历范围扩大一倍,即,2N
system("pause");
return 0;
}
基于上个方法的改进:
利用数学上的求余运算,消除上述方法的判断:
再补充一种不用判断的方法,纯用算法实现:
类似上述的:
利用布尔运算,也可以不用判断:
还有一种简单的方法,利用条件表达式:
return 0;
}
由上联想,将条件表达式和数学函数一起用:
return 0;
}
第三种想法
:利用循环分别将奇数和偶数存在数组的相应位置中。
关键点:对数组下标的计算。
for(int i=1;i!=10;++i)
{
if (i%2!=0)
iNum[i/2] = i; // 奇数放在数组前半部分
else
iNum[5+i/2 -1] = i; // 偶数放在数组后半部分
}
// 格式化,添加换行符
sprintf(sResult, "%d/n%d/n%d/n%d/n%d/n%d/n%d/n%d/n%d/n",
iNum[0],iNum[1],iNum[2],iNum[3],iNum[4],iNum[5],iNum[6],iNum[7],iNum[8]);
printf(sResult);
return 0;
}
第四种想法
:设计一个类,在构造函数中打印奇数,在循环中打印偶数。
关键点:对类的设计。
public:
printer()
{
even_ = 0;
if ( counter%2 != 0)// 打印奇数
std::cout<< counter << std::endl;
else
even_ = counter;
counter++;
}
~printer()
{
}
void print_even()
{
if (even_!=0)
std::cout<< even_ << std::endl;
}
};
int main(int argc, char** argv)
{
printer print[9];
for (int i = 0 ; i < 9 ; ++i)// 打印偶数
{
print[i].print_even();
}
return 0;
}
一些奇特的方法
[1]
for(int i=1;i<10;fprintf(f[(i+1)%2],"%d/n",++i))
;
return 0;
}
原理:
con表示控制台,输入指的是键盘,输出指的是显示器;
当然可以换成别的: 换成 prn 就会输出到打印机;换成 abc.txt 就输出到文件 abc.txt 了。
上述代码修改如下:
for(int i=1;i<10;fprintf(f[(i+1)%2],"%d/n",++i))
;
return 0;
}
/*
f[0]将奇数1,3,5,7,9写入当前目录下的abc.txt文件中;
f[1]将偶数2,4,6,8在控制台中输出显示。
*/
[2]