首页 > 试题广场 >

直方图

[编程题]直方图
  • 热度指数:1774 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
又到年底统计报表的时间了。我们公司一共生产“0”到“9”十种产品,现在给你一份销售记录,请你帮忙绘制一份直方图。

输入描述:
输入包含多组数据,每组数据包含一个字符串s。
s仅包含数字,长度不超过100。


输出描述:
对应每一组数据,依次为十种产品绘制高度等于其销量的“*”柱图。
直方图的高度等于数据中数量最多产品的个数,如果某种产品高度不到直方图的高度,用空格补全。
直方图下方依次输出0到9作为坐标。
示例1

输入

0123456789123
123012312

输出

 ***      
**********
0123456789
 **       
 ***      
****      
0123456789
#include<iostream>
#include<string>
using namespace std;

//以数字出现次数(产量)为纵坐标画柱状图
int main(){
    string a;
    while(cin>>a){
        int i,j,max=0,num[10]={0};
        for(i=0;i<a.length();i++)num[a[i]-'0']++; //统计每个数字出现的次数
        for(i=0;i<10;i++)if(num[i]>max)max=num[i]; //找到最大次数,即柱状图层数
        for(i=max;i>0;i--){ //画柱状图,i为当前层数
            for(j=0;j<10;j++){if(i>num[j])cout<<' ';else cout<<'*';} //画每一层,次数小于层数输出空格
            cout<<endl;
        }
        cout<<"0123456789"<<endl; //标出横轴
    }
    return 0;
}

编辑于 2018-02-14 16:55:41 回复(1)
#include<stdio.h>
#include<string.h>
int main (){//the shorter,the better.
    int i,m,len,p[10];char s[101];
    for(;~scanf("%s",s);printf("0123456789\n")){
        for(len=strlen(s),memset(p,0,sizeof(p)),m=i=0;i<len;++p[s[i]%48],m=p[s[i]%48]>m?p[s[i]%48]:m,++i);
        for(;m>0;--m,printf("\n"))for(i=0;i<10;printf(p[i++]<m?" ":"*"));
    }
}

发表于 2018-02-03 15:07:10 回复(1)

python solution:

import sys
from collections import Counter

#从上到下输出直方图
def printHistogram(string):
    c = Counter(string)
    height = c.most_common(1)[0][1]
    for i in range(0, height):
        layer = "" #每一层的字符串
        for num in "0123456789":
            if c[num] + i >= height:  #这个if else是核心逻辑
                layer += "*"
            else:
                layer += " "
        print (layer)

    print("0123456789")


for i in sys.stdin.readlines():
    printHistogram(i)
编辑于 2017-11-17 09:41:52 回复(0)
没看懂,谁通俗的解释下?!
发表于 2017-08-02 09:08:40 回复(4)
num = input()
temp = str(num)
count = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in temp:
    if i == "0":
        count[0] += 1
    elif i == "1":
        count[1] += 1
    elif i == "2":
        count[2] += 1
    elif i == "3":
        count[3] += 1
    elif i == "4":
        count[4] += 1
    elif i == "5":
        count[5] += 1
    elif i == "6":
        count[6] += 1
    elif i == "7":
        count[7] += 1
    elif i == "8":
        count[8] += 1
    elif i == "9":
        count[9] += 1
maxV = max(count)
for i in range(maxV):
    for j in range(10):
        if count[j] < (maxV - i):
            print(" ", end='')
        else:
            print("*", end='')
    print("")
print("0123456789")

为啥自己在VScode中运行这个代码完全没问题,而上传后直接说答案错误?还请大神排忧解难😭
发表于 2020-07-16 15:01:17 回复(1)
#include<stdio.h>
#include<string.h>

int main(){
    char res[105]; //输入的字符串
    int num[15];    //对每个数的出现次数的记录
    while(~scanf("%s",&res)){
        int i,j,k,h,maxx;
        maxx=0;
        memset(num,0,sizeof(num)); //如果是int 只能初始化0或-1
        for(i=0;i<strlen(res);i++){
            num[res[i]-'0']++;
        }
        for(j=0;j<=9;j++){
            if(num[j]>=maxx){
                maxx=num[j];
            }
        }
        for(k=maxx;k>0;k--){
            for(h=0;h<=9;h++){
                if(num[h]>=k){
                    printf("*");
                }
                else{
                    printf(" ");
                }
            }
            printf("\n");
        }
        printf("0123456789\n");
    }
}

发表于 2019-05-27 14:41:46 回复(0)
#include <bits/stdc++.h>
#define PI 3.1415927
using namespace std; 
typedef  long long ll;
int arr[10];
int main(void)  
{     
    string s;
    while(cin>>s)
    {
        fill(arr,arr+10,0);
        int Max=-1;
        for(int i=0;i<s.size();i++)
        {
            arr[s[i]-'0']++;
            Max=max(Max,arr[s[i]-'0']);
        }
        for(int i=Max;i>0;i--)
        {
            for(int j=0;j<=9;j++)
            {
                if(arr[j]==i)
                {
                    cout<<'*';
                    arr[j]--;
                }
                else
                    cout<<' ';
            }
            cout<<endl;
        }
        
        cout<<"0123456789"<<endl;
    }    
    return 0;
}  

发表于 2018-08-01 21:45:42 回复(0)
// 先统计每样产品的个数,然后选出最高(数量最多)的产品;
//从最高的层数开始画*,如果数量匹配则输出,同时数量减一;
//数量与高度不相等则输出' ',这样就实现了。
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string in;
    while (cin>>in)
    {
        int cnt[10] = {0};
        for (int i=0; i<in.length(); i++)
        {
            cnt[in[i]-'0']++;
        }
        int height = 0;
        for (int i=0; i<10; i++)
        {
            if (height < cnt[i])
                height = cnt[i];
        }
        for (int j=height; j>0; j--)
        {
            for (int i=0; i<10; i++)
            {
                if (cnt[i] == j)
                {
                    cout<<'*';
                    cnt[i]--;
                }
                else 
                    cout<<' ';
            }
            cout<<endl;
        }
        cout<<"0123456789"<<endl;
    }
    system("pause");
    return 0;
}

发表于 2018-01-11 10:42:48 回复(0)
C最简写法
#include<stdio.h>
int main(int argc, char** argv){
	char s[100];
	while(gets(s)){
		int data[10]={0,0,0,0,0,0,0,0,0,0}; 
        int index=0;    //s index
		while(s[index]){ data[s[index++]-'0']++; }
		int max=-1;
		for(int i=0; i<10; ++i){ if(data[i]>max) max=data[i]; }
		for(int i=0; i<max; ++i){
			for(int j=0; j<10; ++j){
				if(data[j]-max+i >= 0) printf("*");
				else printf(" ");
			}
			printf("\n");
		}
        printf("0123456789\n");
	}
	return 0;
}
编辑于 2022-01-14 11:26:18 回复(0)
import java.util.*;
public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            String s = sc.nextLine();
            Map<Integer,Integer> map = new HashMap<>();
            int max = -1;
            int max_index = -1;
            for(int i = 0 ; i < s.length() ; i++) { // 遍历字符串
                int n = s.charAt(i) - '0';
                if(map.containsKey(n)) {
                    map.put(n,map.get(n) + 1);
                    if(max <= map.get(n)) { // 更新最大值
                        max = map.get(n);
                        max_index = n;
                    }
                } else {
                    map.put(n, 1);
                }
            }
            // 输出
            for(int i = max ; i > 0 ; i--) {
                for(int j = 0 ; j < 10 ; j++) {
                    if(map.containsKey(j)) {
                        if(i <= map.get(j)) {
                            System.out.print("*");
                        } else {
                            System.out.print(" ");
                        }
                    } else {
                        System.out.print(" ");
                    }
                }
                System.out.println();
            }
            System.out.println("0123456789");
        }
    }
}

发表于 2021-11-30 17:32:06 回复(0)


首先统计各个数字出现的次数,并找出出现最多的次数
然后从[maxCnt,1]高度区间依次输出,如果数字j出现的次数不少于i次,则输出*,否则输出空格。

#include <iostream>
(720)#include <cstring>
using namespace std;

int main() {
    char str[101] = {'\0'};
    while (scanf("%s", str) != -1) {
        int count[10] = {0}, maxCnt = 0;
        //统计各个数字出现的次数,并找出出现最多的次数
        for (int i = (int)strlen(str) - 1; i >= 0; --i) {
            if (++count[str[i] - '0'] > maxCnt) {
                maxCnt = count[str[i] - '0'];
            }
        }
        //从[maxCnt,1]高度区间依次输出
        for (int i = maxCnt; i > 0; --i) {
            //如果数字j出现的次数不少于i次,则输出*,否则输出空格
            for (int j = 0; j < 10; ++j) {
                printf("%c", (count[j] < i ? ' ' : '*'));
            }
            printf("\n");
        }
        printf("0123456789\n");
    }
    return 0;
}
————————————————
版权声明:本文为CSDN博主「hestyle」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://hestyle.blog.csdn.net/article/details/104728241
发表于 2020-03-08 10:38:34 回复(0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    char s[100];
    while(gets(s))
    {
        int num[10] = {0};//记录等于0~9的值的数量
        for(int i = 0; s[i] != '\0'; i++)
            num[(int)(s[i] - '0')]++;
        int max_loc = 0;
        int i;
        for(i = 1; i < 10; i++)
        {
            if(num[i] > num[max_loc])
                max_loc = i;
        }
        int temp = num[max_loc];
        for(i = 0; i < 10; i++)
            num[i] -= temp;
        while(temp--)
        {
            for(i = 0; i < 10; i++)
            {
                if(num[i] < 0)
                    printf(" ");
                else
                    printf("*");
                num[i]++;
            }
            printf("\n");
        }
        printf("0123456789\n");
    }
 
    return 0;
}

编辑于 2020-03-04 14:48:52 回复(0)
#include<iostream>
#include<cstring>
using namespace std;

int main(){
    string s;
    while(cin>>s){
        int a[10]={0};
        int max=0;
        int maxk;
        for(int i=0;i<s.size();i++){
            int k=0;
            k=s[i]-'0';
            ++a[k];
            if(a[k]>max) {max=a[k];}
        }
        while(max>0){
            for(int p=0;p<10;p++){
                if(a[p]==max){
                    cout<<'*';
                    a[p]--;
                }
                else cout<<' ';
            }
            max--;
            cout<<endl;
        }
        cout<<"0123456789"<<endl;
    }
    return 0;
}
编辑于 2020-02-04 22:22:26 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String string = input.nextLine();
            Map<Integer, Integer> map = new LinkedHashMap<>();
            int[] index = new int[10];
            for (char var: string.toCharArray()) {
                index[var - '0']++;
            }
            for (int i = 0; i < index.length; i++) {
                map.put(i, index[i]);
            }
            List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer, Integer>>(map.entrySet());
            Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>(){
                @Override
                public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                    return o2.getValue() - o1.getValue();
                }
            });
            // System.out.println(list);
            int max = list.get(0).getValue();
            int temp = max;
            for (int i = 0; i < max; i++) {
                for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
                    if (entry.getValue() == temp) {
                        System.out.print("*");
                        int t = entry.getValue() - 1;
                        map.put(entry.getKey(), t);
                    }
                        else System.out.print(" ");
                }
                temp--;
                System.out.println();
            }
            String num = "0123456789";
            System.out.println(num);
        }                
    }
}

发表于 2019-09-03 11:10:16 回复(0)
#include<iostream>
#include <cstring>
using namespace std;
int main() {
    int a[10],m;
    string s;
    while(cin>>s) {
        m=0;
        memset(a,0,sizeof(a));
        for(int i=0;i<s.length();i++) {
            a[int(s[i])-48]++;
        }
        for(int i=0;i<10;i++) {
            if(a[i]>m) {
                m=a[i];
            }
        }
        while(m--) {
            for(int i=0;i<10;i++) {
                if(a[i]>m) {
                    cout<<"*";
                } else {
                    cout<<" ";
                }
            }
            cout<<endl;
        }
        cout<<"0123456789"<<endl;
    }
    return 0;
}
发表于 2019-08-04 14:34:19 回复(0)
//横轴表示每个产品的坐标(0-9),纵轴表示每个产品出现的次数(从下往上数)
//题目中的例子应该纠正一下

输入例子:
0123456789123
123012312

输出例子:
 ***  //(整体右移动一个单位,这里为修改之后的状态)    
**********
0123456789
 **       
 ***      
****      
0123456789

编辑于 2019-04-04 11:03:01 回复(0)
本题极其鬼畜  我个人在本地测试了多次都没问题,一提交就出错。。。
后来才发现测试样例字符串不全是数字。。。也就是说,如果它给你一个字符串,你得直接输出0123456789\n
这也真是够了。。。
自己的代码

#include<stdio.h>
#include<string.h>
using namespace std;

int main()
{
    char a[101];
    char graph[100][10];
    int count[10];
    while(scanf("%s",a)!=EOF){
        memset(graph,' ',sizeof(graph));memset(count,0,sizeof(count));
        int len = strlen(a); int max = 0;  //记录个数最多的
        bool flag = true;
        for(int i=0;i<len;++i){if(a[i]<'0'||a[i]>'9') flag = false; break; }
        
        if(flag){  //如果全是数字
        for(int i=0;i<len;++i){
            count[a[i]-'0'] ++; if(max<count[a[i]-'0']) max = count[a[i]-'0'];
        }
        //根据count修改garph二维数组 然后打印即可
        for(int i=0;i<max;i++){
            for(int j=0;j<10;j++){
                if(count[j]>0){graph[i][j]='*';count[j]--;}
            }
        }
      for(int i=max-1;i>=0;i--){
           if(i!=max-1) printf("\n");
        for(int j=0;j<10;++j){
            printf("%c",graph[i][j]);
        }
      }
      printf("\n0123456789\n");           
        }
      else printf("0123456789\n");  //如果不全是数字  直接输出坐标
    }
}
发表于 2019-01-02 13:16:09 回复(0)
import java.io.BufferedInputStream;
import java.util.Scanner;

public class Test1031Histogram {
public static void main(String[] args) {     Scanner in = new Scanner(new BufferedInputStream(System.in));     while (in.hasNextLine()) {         String str=in.nextLine();         int []a=new int [10];         for(int i=0;i<str.length();i++){             char ch=str.charAt(i);             a[(int)(ch-'0')]++;         }         int max=getMax(a);         while (max!=0) {         for(int i=0;i<a.length;i++){             if(a[i]==max){                 System.out.print("*");                 a[i]--;             }else {                 System.out.print(" ");             }                                   }         System.out.println();         max=getMax(a);         }         System.out.println("0123456789");              }      }
public static int getMax(int a[]) {     int max=a[0];     for(int i=0;i<a.length;i++){         if(max<a[i]){             max=a[i];         }     }     return max;
}
}

发表于 2018-12-06 19:27:38 回复(0)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
    string ss;
    while(cin>>ss)
    {
        int Hash[10]={0},MAXN=0;
        for(int i=0;i<ss.length();i++)
        {
            Hash[ss[i]-'0']++;
            if(Hash[ss[i]-'0']>MAXN)MAXN=Hash[ss[i]-'0'];
        }
        int num=0;
        for(int i=0;i<10;i++)
        {
            if(Hash[i]!=0)num++;
        }
        char out[101][101];
//        for(int i=0;i<101;i++)
//            fill(out,out+101,' ');
        for(int i=0;i<101;i++)
        {
            for(int j=0;j<101;j++)
                out[i][j]=' ';
        }
        for(int i=0;i<10;i++)
        {
            if(Hash[i]>0)
            {
                for(int j=0;j<Hash[i];j++)
                {
                    out[j][i]='*';
                }
            }
        }
        for(int i=MAXN-1;i>=0;i--)
        {
            for(int j=0;j<10;j++)
            {
                cout<<out[i][j];
            }
            cout<<endl;
        }
        cout<<"0123456789"<<endl;
    }
    return 0;
}

发表于 2018-09-10 18:21:10 回复(0)
思路:就是绘制直方图。
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;
int main(void)
{
    string s;
    while (cin >> s)
    {
        int arr[10] = {0};
        for (int i = 0; i < s.size(); i++)
        {
            arr[s[i] - '0']++;
        }
        int max = 0;
        for (int j = 0; j < 10; j++)
        {
            if (arr[j] > max)
            {
                max = arr[j];
            }
        }
        for (int i = max; i > 0; i--)
        {
            for (int j = 0; j < 10; j++)
            {
                if (arr[j] >= i)
                {
                    cout << "*";
                }
                else
                {
                    cout << " ";
                }
                if (j == 9)
                {
                    cout << endl;
                }
            }
        }
        cout << "0123456789" << endl;
    }
}

发表于 2018-08-13 15:28:12 回复(0)