我正在尝试创建一个显示条形图的程序,*最大数量*可以是40.我已经完成了所有工作,但对代码有疑问。有没有更好的方法,因为你可以看到我必须使用以下两次回到原始地址:
p_bar_length = p_bar_length - size;
有更好的方法吗?
#include <iostream>
using namespace std;
const int MAX_SPLATS = 40;
void bar_chart(double values[], int size)
{
double largest = values[0]; //assign first element to be the largest
//Find the largest value
for (int i = 1; i < size; i++)
{
if (largest < values[i]) // check to see if there is something larger
{
largest = values[i];
}
}
// Find the number of spalts to use
// with the precent based on the largest value
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
*p_bar_length = (values[i] / largest) * MAX_SPLATS;
p_bar_length++; // Go to next memory address
}
// Go back to the orignal memory address
p_bar_length = p_bar_length - size;
// Pritnt the correct number of splats
for (int i = 0; i < size; i++)
{
for (int j = 0; j < *p_bar_length; j++)
{
cout << "*";
}
p_bar_length++;
cout << endl;
}
// Go back to the orignal memory address
p_bar_length = p_bar_length - size;
delete[] p_bar_length;
}
int main()
{
double values[6] = { 22, 40, 28, 26, 14, 46};
int val_size = 6;
bar_chart(values, val_size);
system("pause");
return 0;
}
答案 0 :(得分:8)
由于这是C ++,最好的方法是不来使用指针;相反,使用std::vector
。
也就是说,您也可以将指针视为数组,只需访问p_bar_length[i]
给定位置0 <= i < length
,而不是递增指针。
答案 1 :(得分:6)
使用数组索引:
,而不是递增指针p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;
或使用指针算法:
*(p_bar_length + i) = (values[i] / largest) * MAX_SPLATS;
答案 2 :(得分:4)
由于您将其标记为C ++,我建议您使用标准库。
你的程序比C ++更加C,但是如果c对你来说没什么可改进的话
另一方面,使用vector
和algorithm
,您不需要乱用指针。使用C ++ 11,它可以删除以前与模板和迭代器相关联的粗糙边缘。
快速拍摄:
#include <iostream>
#include <vector>
#include <algorithm>
const int MAX_SPLATS = 40;
template <typename C>
void bar_chart(const C& values)
{
if (std::distance(values.begin(), values.end())<1)
return; // do some error handling
auto largest = *std::max_element(values.begin(), values.end());
// Find the number of splats to use with the percent based on
// the largest value
std::vector<int> bars(values.size());
std::transform(values.begin(), values.end(), bars.begin(),
[=] (double d) { return (d/largest)*MAX_SPLATS; });
// Print the correct number of splats
std::for_each(bars.begin(), bars.end(),
[](int val){ std::cout << std::string(val, '*') << std::endl; });
}
int main()
{
std::vector<double> values = { 22, 40, 28, 26, 14, 46 };
bar_chart(values);
std::cin.get();
return 0;
}
答案 3 :(得分:4)
如果您使用for
中的std :: max_element,则不需要第一个<algorithm>
循环。
如果计算第三个for
循环中的条形长度,则不需要第二个for
循环。
这样的事情:
void bar_chart(double values[], int size)
{
//Find the largest value
double largest = *std::max_element(values, values + size);
// Print the correct number of splats
for (int i = 0; i < size; i++)
{
int p_bar_length = (values[i] / largest) * MAX_SPLATS;
cout << string(p_bar_length, '*') << endl;
}
}
这样你根本不需要p_bar_length
数组。这只是一个简单的int
。
编辑:您甚至可以替换内部for循环(示例已修改)
答案 4 :(得分:2)
制作指针的另一个副本,以便在循环中使用。更不容易出错。
int* p_bar_length = new (nothrow) int[size];
int* p = p_bar_length;
for (int i = 0; i < size; i++)
{
*p = (values[i] / largest) * MAX_SPLATS;
p++; // Go to next memory address
}
P.S。你为什么使用nothrow
?由于您没有检查从new
返回的值,因此异常将比您返回NULL
指针时的乱码要好得多。
答案 5 :(得分:2)
您可以将p_bar_length视为数组,并使用一致的表示法
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
p_bar_length[i] = (values[i] / largest) * MAX_SPLATS;
}
答案 6 :(得分:0)
二合一怎么样?
int* p_bar_length = new (nothrow) int[size];
for (int i = 0; i < size; i++)
{
*p_bar_length = (values[i] / largest) * MAX_SPLATS;
for (int j = 0; j < *p_bar_length; j++) cout << "*";
cout << endl;
p_bar_length++; // Go to next memory address
}
答案 7 :(得分:0)
这与@mkaes的帖子非常相似,但更进了一步。而不是使用std::transform
创建适当长度的向量,然后std::for_each
创建一个字符串,从每个字符串中获得适当的长度,这将直接从输入创建一个字符串,并直接从std::transform
:
#include <iostream>
#include <array>
#include <algorithm>
#include <string>
#include <iterator>
const int MAX_SPLATS = 40;
template <typename C>
void bar_chart(const C& values)
{
if (std::distance(values.begin(), values.end())<1)
return; // do some error handling
auto largest = *std::max_element(values.begin(), values.end());
std::transform(values.begin(), values.end(),
std::ostream_iterator<std::string>(std::cout, "\n"),
[=](double d) { return std::string((d/largest)*MAX_SPLATS, '*');} );
}
int main() {
std::array<double, 6> values = {22, 40, 28, 26, 14, 46};
bar_chart(values);
return 0;
}
因为它无论如何都在使用C ++ 11,所以我决定使用std::array
,因为它似乎非常适合手头的工作。