为什么编码挑战的解决方案看起来比我的复杂得多,而我的却更简单?
Why does the solution to a coding challenge seem so much more complex than mine, while mine is simpler?
我正在学习 C++ 课程,每个部分都有一个挑战。对于最近的挑战,我们要从一个文本文件中取出三种不同类型的数据,在一行中有三种数据类型,每种数据类型由一个制表符分隔(您将看到只有两个制表符)。
1\tBox of 64 Pixels\t64 RGB pixels in a decorative box
2\tSense of Humor\tEspecially dry. Imported from England.
3\tBeauty\tInner beauty. No cosmetic surgery required!
4\tBar Code\tUnused. In original packaging.
第一种是SKU号,第二种是品名,第三种是描述。您必须将所有这些信息放在一个结构中。
我的解决方案:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
struct CI
{
int sku = 0;
string name = "";
string desc = "";
};
const int MAXSTRING = 1024;
int main()
{
const char *itemsPath = "items.txt";
FILE *items = fopen(itemsPath, "r");
CI changed1;
CI changed2;
CI changed3;
CI changed4;
vector<CI> changed = {changed1, changed2, changed3, changed4};
vector<string> lines = vector<string>();
char buffer[MAXSTRING];
int tab = 0;
int counter = 0;
while (fgets(buffer, MAXSTRING, items))
{
lines.push_back(buffer);
}
for (string &s : lines)
{
for (char &c : s)
{
if (c == '\t')
{
tab++;
continue;
}
if (tab == 0)
{
changed[counter].sku = c - '0';
}
else if (tab == 1)
{
changed[counter].name += c;
}
else if (tab == 2)
{
changed[counter].desc += c;
}
}
tab = 0;
counter++;
if (counter == 4)
{
break;
}
}
for (int i = 0; i < 4; i++)
{
cout << "sku: " << changed[i].sku << ", name: " << changed[i].name << ", desc: " << changed[i].desc;
}
fclose(items);
return 0;
}
实际解决方案:
// 08_solution.cpp by Bill Weinman <http://bw.org/>
// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
constexpr size_t maxstring = 1024; // size of line buffer
constexpr size_t name_size = 32; // size of name string
constexpr size_t desc_size = 128; // size of description string
constexpr const char *filename = "/Users/billw/Desktop/ExerciseFiles/Chap08/items.txt";
constexpr size_t max_split = 15;
constexpr char tab_char = '\t';
struct Item
{
int sku; // stock keeping unit
char name[name_size]; // item name
char desc[desc_size]; // item description
};
// str_seps(s) -- returns an array where each element
// represents the position of a separator in the string
// first element is a count
size_t *str_seps(const char *s, size_t len)
{
static size_t indicies[max_split + 1];
size_t &count = indicies[0];
if (len < 3)
return indicies;
for (size_t &z : indicies)
z = 0; // zero out the array
for (size_t i = 0; i < len; ++i)
{
if (s[i] == tab_char)
{
++count;
indicies[count] = i;
if (count >= max_split)
break;
}
}
return indicies;
}
int main()
{
char buf[maxstring]; // buffer for reading lines in file
// open the file
FILE *fr = fopen(filename, "r");
if (!fr)
{
const char *errstr = strerror(errno);
printf("cannot open file (%d): %s\n", errno, errstr);
return 1;
}
// read loop
while (fgets(buf, maxstring, fr))
{
size_t len = strnlen(buf, maxstring);
if (len <= 5)
continue;
// trim the newline from the end of the string
if (buf[len - 1] == '\n')
{
buf[len - 1] = 0;
--len;
}
size_t *split3 = str_seps(buf, len);
if (split3[0] < 2)
break;
buf[split3[1]] = buf[split3[2]] = 0; // change separators to terminators
Item current_item;
current_item.sku = atoi(buf);
strncpy(current_item.name, buf + split3[1] + 1, name_size - 1);
strncpy(current_item.desc, buf + split3[2] + 1, desc_size - 1);
printf("sku: %d, name: %s, desc: %s\n", current_item.sku, current_item.name, current_item.desc);
}
return 0;
}
已编辑:具体来说,我的代码是否不安全,是否检查文件是否已打开:
if (!fr)
{
const char *errstr = strerror(errno);
printf("cannot open file (%d): %s\n", errno, errstr);
return 1;
}
需要。
关于为什么它看起来很奇怪的一个提示是在一开始:
// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
所以 20 年前的代码,只使用 C 库,可能不是很棒的 C++。
另一方面,代码如下:
CI changed1;
CI changed2;
CI changed3;
CI changed4;
vector<CI> changed = {changed1, changed2, changed3, changed4};
也可能只对编写它的人显而易见。 :-)
猜想和vector<CI> changed(4);
的意思一样,不过想了想
我正在学习 C++ 课程,每个部分都有一个挑战。对于最近的挑战,我们要从一个文本文件中取出三种不同类型的数据,在一行中有三种数据类型,每种数据类型由一个制表符分隔(您将看到只有两个制表符)。
1\tBox of 64 Pixels\t64 RGB pixels in a decorative box
2\tSense of Humor\tEspecially dry. Imported from England.
3\tBeauty\tInner beauty. No cosmetic surgery required!
4\tBar Code\tUnused. In original packaging.
第一种是SKU号,第二种是品名,第三种是描述。您必须将所有这些信息放在一个结构中。
我的解决方案:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
struct CI
{
int sku = 0;
string name = "";
string desc = "";
};
const int MAXSTRING = 1024;
int main()
{
const char *itemsPath = "items.txt";
FILE *items = fopen(itemsPath, "r");
CI changed1;
CI changed2;
CI changed3;
CI changed4;
vector<CI> changed = {changed1, changed2, changed3, changed4};
vector<string> lines = vector<string>();
char buffer[MAXSTRING];
int tab = 0;
int counter = 0;
while (fgets(buffer, MAXSTRING, items))
{
lines.push_back(buffer);
}
for (string &s : lines)
{
for (char &c : s)
{
if (c == '\t')
{
tab++;
continue;
}
if (tab == 0)
{
changed[counter].sku = c - '0';
}
else if (tab == 1)
{
changed[counter].name += c;
}
else if (tab == 2)
{
changed[counter].desc += c;
}
}
tab = 0;
counter++;
if (counter == 4)
{
break;
}
}
for (int i = 0; i < 4; i++)
{
cout << "sku: " << changed[i].sku << ", name: " << changed[i].name << ", desc: " << changed[i].desc;
}
fclose(items);
return 0;
}
实际解决方案:
// 08_solution.cpp by Bill Weinman <http://bw.org/>
// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
constexpr size_t maxstring = 1024; // size of line buffer
constexpr size_t name_size = 32; // size of name string
constexpr size_t desc_size = 128; // size of description string
constexpr const char *filename = "/Users/billw/Desktop/ExerciseFiles/Chap08/items.txt";
constexpr size_t max_split = 15;
constexpr char tab_char = '\t';
struct Item
{
int sku; // stock keeping unit
char name[name_size]; // item name
char desc[desc_size]; // item description
};
// str_seps(s) -- returns an array where each element
// represents the position of a separator in the string
// first element is a count
size_t *str_seps(const char *s, size_t len)
{
static size_t indicies[max_split + 1];
size_t &count = indicies[0];
if (len < 3)
return indicies;
for (size_t &z : indicies)
z = 0; // zero out the array
for (size_t i = 0; i < len; ++i)
{
if (s[i] == tab_char)
{
++count;
indicies[count] = i;
if (count >= max_split)
break;
}
}
return indicies;
}
int main()
{
char buf[maxstring]; // buffer for reading lines in file
// open the file
FILE *fr = fopen(filename, "r");
if (!fr)
{
const char *errstr = strerror(errno);
printf("cannot open file (%d): %s\n", errno, errstr);
return 1;
}
// read loop
while (fgets(buf, maxstring, fr))
{
size_t len = strnlen(buf, maxstring);
if (len <= 5)
continue;
// trim the newline from the end of the string
if (buf[len - 1] == '\n')
{
buf[len - 1] = 0;
--len;
}
size_t *split3 = str_seps(buf, len);
if (split3[0] < 2)
break;
buf[split3[1]] = buf[split3[2]] = 0; // change separators to terminators
Item current_item;
current_item.sku = atoi(buf);
strncpy(current_item.name, buf + split3[1] + 1, name_size - 1);
strncpy(current_item.desc, buf + split3[2] + 1, desc_size - 1);
printf("sku: %d, name: %s, desc: %s\n", current_item.sku, current_item.name, current_item.desc);
}
return 0;
}
已编辑:具体来说,我的代码是否不安全,是否检查文件是否已打开:
if (!fr)
{
const char *errstr = strerror(errno);
printf("cannot open file (%d): %s\n", errno, errstr);
return 1;
}
需要。
关于为什么它看起来很奇怪的一个提示是在一开始:
// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
所以 20 年前的代码,只使用 C 库,可能不是很棒的 C++。
另一方面,代码如下:
CI changed1;
CI changed2;
CI changed3;
CI changed4;
vector<CI> changed = {changed1, changed2, changed3, changed4};
也可能只对编写它的人显而易见。 :-)
猜想和vector<CI> changed(4);
的意思一样,不过想了想