首先,我开始学习Java,并使用星号打印出一个条形图。我已经将算法放在如何打印正值上,我想我已经掌握了处理负值所需要做的事情。我无法做到的是将这个想法转化为代码。我正在与之合作:
public class BarChart
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
Random gen = new Random();
// Read for input of array legnth
System.out.print("Enter Array Length: ");
int n = gen.nextInt(6) + 10;
System.out.println(n);
int[] values = new int[n];
int randNum;
for(int i = 0; i < n; i++)
{
// Get random number to add to the array
randNum = gen.nextInt(20) + 1;
values[i] = randNum;
}
print(values);
System.out.println();
values[3] = -2;
// Print each element as asterisks
for(int i = 0; i < values.length; i++)
{
if(values[i] < 0)
{
printAsterisk(values[i] * -1);
System.out.printf("%20d:\n", values[i]);
}
else
{
System.out.printf("%20d:", values[i]);
printAsterisk(values[i]);
System.out.println();
}
}
}
// Methods
/**
* Prints an array
* @param array array
*/
public static void print(int[] array)
{
for(int i = 0; i < array.length; i++)
{
if(i > 0)
{
System.out.print(" | ");
}
System.out.print(array[i]);
}
System.out.println();
}
public static void printAsterisk(int val)
{
for(int i = 0; i < val; i++)
{
System.out.print("*");
}
}
}
这让我接近我想要的,但我得到的是:
Enter Array Length: 14
13 | 13 | 4 | 5 | 11 | 1 | 3 | 13 | 3 | 4 | 19 | 4 | 10 | 10
13:*************
13:*************
4:****
** -2:
11:***********
1:*
3:***
13:*************
3:***
4:****
19:*******************
4:****
10:**********
10:**********
注意:数组长度和元素都是随机确定的。在我上面给出的例子中,我明确地将其中一个元素更改为负值,仅用于测试目的,使用值[3] = -2。
有负值的星号应如下所示:
**[-2]
[5 ]*****
***[-3]
[9 ]*********
我也无法在上面的示例中使用%20d打印我想要的内容。但这不是主要关注的问题。就像在我打印的那样:
5: *****
** -2:
6: ******
**** -4:
我的想法是,我需要从左侧缩进一定量,然后打印必要的星号,然后用括号打印星号的数量。所以我的问题是如何更改代码以生成我想要的输出。
答案 0 :(得分:0)
有负值的星号应如下所示:
**[-2] [5 ]***** ***[-3] [9 ]*********
您可能希望自动调整实际值,例如如果值为-11
,则[]
括号中需要3个字符,[
左侧至少需要11个字符。
这意味着您应首先遍历这些值以确定您需要多少空间。
然后,您可以为printf
动态构建格式字符串,例如如果最小值为-11
且最大值为<= 999,则如下所示:
"%11s[%-3d]%s%n"
然后你给它一个包含*
星的字符串,而不是直接打印它们。最好的方法是使用repeat
辅助方法。
代码可能是这样的:
private static void printArray(int... arr) {
int min = -1, numLen = 1;
for (int val : arr) {
min = Math.min(min, val);
numLen = Math.max(numLen, Integer.toString(val).length());
}
String fmt = "%" + -min + "s[%" + numLen + "d]%s%n";
for (int val : arr) {
if (val >= 0)
System.out.printf(fmt, "", val, repeat('*', val));
else
System.out.printf(fmt, repeat('*', -val), val, "");
}
}
private static String repeat(char c, int len) {
char[] buf = new char[len];
Arrays.fill(buf, c);
return new String(buf);
}
测试
public static void main(String[] args) {
printArray(buildArray(14, -20, 20));
}
private static int[] buildArray(int len, int min, int max) {
Random r = new Random();
int[] arr = new int[len];
for (int i = 0; i < len; i++)
arr[i] = r.nextInt(max - min + 1) + min;
return arr;
}
示例输出
[ 6]******
************[-12]
**[ -2]
[ 5]*****
[ 17]*****************
[ 3]***
****[ -4]
[ 6]******
[ 3]***
[ 3]***
[ 0]
[ 4]****
***************[-15]
*********[ -9]
答案 1 :(得分:0)
你可以将其分解为打印重复的字符,使代码更清晰:
public void printChart(int[] nums) {
int offset = Math.max(0, - IntStream.of(nums).min().getAsInt());
for (int n : nums) {
int space = offset + Math.min(n, 0);
int neg = Math.max(-n, 0);
int pos = Math.max( n, 0);
System.out.println(String.format("%3d ", n) + repeat(" ", space) +
repeat("*", neg) + "|" + repeat("*", pos));
}
}
对于“打印重复字符串”部分,您可以从this question中选择任何解决方案,例如this one,或使用简单的for
循环和缓冲区滚动自己。
public String repeat(String s, int n) {
return new String(new char[n]).replace("\0", s);
}
示例输出,nums = {5, 8, -4, 1, -3}
(不完全像您想要的输出,但很容易适应,恕我直言,这样看起来更好):
5 |*****
8 |********
-4 ****|
1 |*
-3 ***|
答案 2 :(得分:0)
尝试这个,我修改了随机函数以获得负值。事实上,有很多可能解决您的问题,但我刚刚选择修改您的代码。 (最好改变打印星号的方式)
要从左侧打印星号,您可以执行以下操作:
public static void printAsterisk(int val)
{
if(val >= 0) {
for(int i = 0; i < val; i++)
System.out.print("*");
}
else {
val*=-1;
System.out.printf("%"+(18-val)+"s"," ");
for(int i = 0; i < val; i++)
System.out.printf("%1c",'*');
}
}
完整代码:
public class BarChart
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
Random gen = new Random();
// Read for input of array legnth
System.out.print("Enter Array Length: ");
int n = gen.nextInt(6) + 10;
System.out.println(n);
int[] values = new int[n];
int randNum;
for(int i = 0; i < n; i++)
{
// Get random number between -10 and 20
randNum = gen.nextInt(20+1+20) - 10;
values[i] = randNum;
}
values[3] = -2;
print(values);
System.out.println();
// Print each element as asterisks
for(int i = 0; i < values.length; i++)
{
if(values[i] < 0)
{
printAsterisk(values[i]);
System.out.printf("%1d:\n", values[i]);
}
else
{
System.out.printf("%20d:", values[i]);
printAsterisk(values[i]);
System.out.println();
}
}
}
// Methods
/**
* Prints an array
* @param array array
*/
public static void print(int[] array)
{
for(int i = 0; i < array.length; i++)
{
if(i > 0)
{
System.out.print(" | ");
}
System.out.print(array[i]);
}
System.out.println();
}
public static void printAsterisk(int val)
{
if(val >= 0) {
for(int i = 0; i < val; i++)
System.out.print("*");
}
else {
val*=-1;
System.out.printf("%"+(18-val)+"s"," ");
for(int i = 0; i < val; i++)
System.out.printf("%1c",'*');
}
}
}
输出:
4:****
5:*****
29:*****************************
**-2:
11:***********
******-6:
**********-10:
0:
****-4:
18:******************
*-1:
*****-5:
*******-7: