这个系列是在观看Harvard Cs50课程中,做课后ProblemSets的一些记录。
网络上已经存在很多该系列的blogs和videos,该文用以自我记录,并提供给其他和我一样的代码新手+中文使用者一些参考。
包含每个pset中我认为值得注意的points总结,并mark一些优秀解法。
Plurality (Pset3)
Background: Vote for certain candidates, and print out the winner.
strcmp
use strcmp, a function that is defined in string.h header, to compare two strings, and check if a certain string is exsited.
for (int i = 0; i<candidate_count; i++)
{
if (strcmp(candidates[i].name, name ) == 0)
{
candidates[i].votes ++ ;
return true;
}
return false;
How to select the max voted candidate?
- 用 * tracker 和 iterate 迭代* 的思维代替比较 的思维。
- 设置一个值,使之始终 track 目前输入的最大值,不断迭代。
Tips:其他注意的小点
- for loop 中,分隔条件用
;来进行。 - 记住 print 等动作后要用分号;来结束。
- return 的位置:return false 是在某个功能结尾。 [举例]
bool vote(string name)
{
// TODO
for (int i = 0; i<candidate_count; i++)
{
if (strcmp(candidates[i].name, name ) == 0)
{
candidates[i].votes ++ ;
return true;
}
}
return false;
// 这个地方写错了 return 的位置,导致了 bug 出现。
}
int argc: 用来记录输入在命令行的字符串个数;string argv:用来记录输入在命令行的指令- 上述两个命令需要载入
#include <string.h>;
Pset4 filter
Background 背景知识
Bitmaps
- 24-bit color 类似 BMP、JPEG、PNG 的文件,支持使用 24-bit color,即,每个像素(pixel)使用 24 个 bits。 BMP 文件一般支持 1-,4-,8-,16-,24-,以及 32-bit color。 [Example: 如何表示 Red]
R | G | B
0xff | 0x00 | 0x00
pure red | no green | no blue
[TOC]
2. BITMAP 中的BITMAPFILEHEADER
- 存储文件尺寸,height and width;
- 存储在这个 header 中,长度为 14bytes(14*8 个 bits);
- BITMAP 中的
BITMAPINFOHEADER
- 长度为 40bytes。
- 在 实际的bitmap 中,色彩是反过来存储的,即 RGB 的顺序实际上是 BGR,例如
0000ff代表的其实是red。
常见的图像处理
- Grayscale 变为灰度图像
- 当图像变为灰度值时,RGB 三个值应该是相同的(才能混合出灰度的形态)
- 使用 RGB 的平均值来确定灰度后像素的值。
- Sepia 处理为红褐色调(an old-timey feel)
- 将原有的每个像素 RGB 值通过特定算法改变,最终呈现出红褐色调的感觉。
- 有许多种处理的算法,以下举例一种算法:
sepiaRed = .393 * originalRed + .769 * originalGreen + .189 * originalBlue
sepiaGreen = .349 * originalRed + .686 * originalGreen + .168 * originalBlue
sepiaBlue = .272 * originalRed + .534 * originalGreen + .131 * originalBlue
1、2 处理起来都不复杂。 关键是一定要记住 declare 每个变量的类型。 以及在做 grey 的时候不知道为什么遇到了 segmentation fault,重新搞了一遍有没有了。
- Relection 镜像处理
- 记住在 bitmap 中使用了一个 2-dimensional array 来表示像素的位置;
- 通过算法改变每个像素的位置后,即可实现相应的镜像;
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
// iterate through the array until you get to the mid-point
for (int j = 0; j < (width/2); j++)
{
RGBTRIPLE temp = image[i][j];
//just like how [0][9]...[4][5], [i] will swap with [total-1-i]
image[i][j] = image[i][width - (j + 1)];
image[i][width - (j + 1)] = temp;
}
}
return;
}
- Blur 模糊处理
- 将特定的 pixel 色值与周围 pixel 色值的求取平均值,并将这些 pixels 赋予新的色值。
- 周围的含义:类似扫雷游戏原理。 这个好难,是俺第一次接触分情况讨论的问题。
- 情况 1:该像素周围(连同自身)一共有 9 个 pixel,即处于中间地带;
- 情况 2:该像素周围(连同自身)一共有 6 个 pixel,即处于边上;
- 情况 3:该像素周围(连同自身)一共有 4 个 pixel,即处于角上; 目前我可以看懂的一种解法:完全分情况讨论,并且把左边右边上下左右角都分开情况(可以通过[i+1/-1]等方式较为轻松但写起来很繁复实现)。
stackoverflow 上还有人给出了用矩阵简洁判断的方式,但我矩阵都快忘干了,目前没有力气研究。先码着等我想起矩阵咋算再来看吧。