C - 如何在星号

时间:2017-03-11 16:46:14

标签: c arrays for-loop plot printing

输出应该是这样的:

                   *********************
                   *                   *
                   *                   *
                   *                   *
                   *                   *
**********  ********                   *
*        *  *                          *
*        *  *                          *    
*        ****                          *
*                                      *
*                                      *  
*                                      *
*                                      *
*                                      *
*                                      *

输入是坐标列表(开始,高度),其中begin表示左x坐标,height表示条带的高度。我编码的内容:

//Input: ((1, 10), (10, 7), (13, 16), (20, 15), (40, 0))
int beginArr[NUM_STRIPS];//sorted array of the x-coordinates
int heights[NUM_STRIPS]; //height/y-coordinates
//Assume that the tallest strip is 40
for(int i = 0; i < 40; i++){
    for(int j = 0; j < beginArr[NUM_STRIPS-1]; j++){
        for(int k = 0; k < NUM_STRIPS-1; k++){
            if(isElementOf(beginArr, j) && i >= heights[k] && i <= heights[k+1]){
                printf("*");
            }else if(isElementOf(heights, i) && j >= beginArr[k] && j <= beginArr[k+1]){
                printf("*");
            }else{
                printf(" ");
            }
         }
    }
    printf("\n");
}

我的代码令人尴尬不正确,因为它没有考虑新条带的开始或终止的位置和时间。逻辑部分是我被困住的地方所以非常感谢任何帮助。

编辑:

x,y坐标可以想象为2d数组。在以上示例的情况下:

int xy[][2] = {{1, 10}, {10, 7}, {13, 16}, {20, 15}, {40, 0}};

从我对此的解释来看,最左边的条形矩形从x = 1({1, 10})开始并保持10的高度直到x = 10({10, 7}),这意味着很好高度= 10时x = 1到10的星号。第二个条带从x = 10({10, 7})开始并保持7的高度,直到x = 13({13, 16}),依此类推。

1 个答案:

答案 0 :(得分:2)

这是我想出的。内联评论应该清楚地表明这里发生了什么,希望如此。

我填充了矩形,让它作为练习让你只填写数据的开头和结尾,或者只绘制 空白区旁边的矩形。

您还必须更改输入。

我认为我所做的和你正在做的事情之间的最大区别在于,我在数据中进行了一些不同的传递,第一次计算每个矩形的数据。 width(使未来的计算更简单,更直接)和绘图的大小,第二个填写内存中的绘图。注意我反过来绘制它,然后先绘制顶线,以简化绘图的逻辑,但这可以改变。最后,我首先将数据绘制到内存中,然后在屏幕上绘制,这简化了在绘制星号之前插入多少空格的逻辑。

输出,有用于stderr的信息:

$ gcc -o rects t.c --std=c99 && ./rects
Plot is 20 by 16
Strip 1/8, 2 x 3 @ 0
Strip 2/8, 3 x 10 @ 2
Strip 3/8, 4 x 16 @ 5
Strip 4/8, 2 x 7 @ 9
Strip 5/8, 4 x 1 @ 11
Strip 6/8, 2 x 12 @ 15
Strip 7/8, 3 x 6 @ 17
Strip 8/8, 0 x 0 @ 20
_____****___________
_____****___________
_____****___________
_____****___________
_____****______**___
_____****______**___
__*******______**___
__*******______**___
__*******______**___
__*********____**___
__*********____*****
__*********____*****
__*********____*****
***********____*****
***********____*****
********************

最后,好的东西:

#include <stdio.h>
#include <stdlib.h>

/*
instead of drawing from the top down,
wouldn't it be easier to plot the image into
memory upside down, and then print the lines
in reverse?
*/

// the strip is assumed to end when the next strip starts
// width can therefore be precomputed which will
// simplify the display logic significantly.
typedef struct {
    unsigned int start;
    unsigned int height;
    unsigned int width;
} strip;

// for simplicity, I'll assume these are in order of
// starting position.  They could be sorted to avoid
// this assumption
int main(int argc, char **argv) {
    // we could compute this if we were
    // taking dynamic input
    unsigned int striplen = 8;
    strip strips[] = {
        { 0,  3, 0 },
        { 2, 10, 0 },
        { 5, 16, 0 },
        { 9,  7, 0 },
        { 11, 1, 0 },
        { 15,12, 0 },
        { 17, 6, 0 },
        { 20, 0, 0 }
    };
        // the width of the last strip is 0 and its height must be 0 to 'finish' the strips
        // otherwise we'd actually need to konw the widths of each strip ( which would
        // be a more complete model for the data, but we'll make do without it  by
        // making the assumption that the last strip is 0)

    // we'll discover the "size" of the full plot
    // and set up the widths
    unsigned int plot_width = 0;
    unsigned int plot_height = 0;
    unsigned int laststart = 0;
    for( unsigned int i = 0; i < striplen; i++){
        if( plot_height < strips[i].height ) {
            plot_height = strips[i].height;
        }
        if( i > 0 ){
            // set the width of the previous strip from the difference of their
            // starting positions
            strips[i-1].width = strips[i].start - strips[i-1].start;
            // we can now add the width to the total.  Since the
            // width and height of the last strip are required to be 0,
            // we don't need to worry about the fact that the last width isn't
            // taken into account.
            plot_width += strips[i-1].width;
        }
    }
    // plot the rectangles filled, because it's easier to deal with
    // their intersections that way.
    // when we draw them, we can use the in-memory plot to decide
    // whether an asterisk is an edge or fill
  fprintf( stderr, "Plot is %u by %u\n", plot_width, plot_height );
    char* plot_data = calloc( plot_height * plot_width, sizeof(char) );
    for( unsigned int i = 0; i < striplen; i++){
    fprintf( stderr, "Strip %u/%u, %u x %u @ %u \n", i+1, striplen, strips[i].width, strips[i].height, strips[i].start );
        for( unsigned int x = strips[i].start; x < strips[i].start + strips[i].width; x++){
            for( unsigned int y = 0; y < strips[i].height; y++){
                plot_data[plot_width * y + x] = '*';
            }
        }
    }
    // now we can finally draw it, in reverse order to make it right side up
    for( signed int y = plot_height - 1; y >= 0; y--){
        for( unsigned int x = 0; x < plot_width; x++){
            printf("%c", ( plot_data[y * plot_width + x] == 0 ? '_' : '*' ) );
      }
      printf("\n");
  }
    return 0;
}