C-如何用星号绘制相邻矩形条的轮廓

C-如何用星号绘制相邻矩形条的轮廓,c,arrays,for-loop,plot,printing,C,Arrays,For Loop,Plot,Printing,输出应如下所示: ********************* * * * * * * * * ********** ********

输出应如下所示:

                   *********************
                   *                   *
                   *                   *
                   *                   *
                   *                   *
**********  ********                   *
*        *  *                          *
*        *  *                          *    
*        ****                          *
*                                      *
*                                      *  
*                                      *
*                                      *
*                                      *
*                                      *
输入是一个坐标列表(begin,height),其中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=1(
{1,10}
)开始,并在x=10(
{10,7}
)之前保持10的高度,这意味着在高度=10时,x=1到10之间会有星号。第二条从x=10(
{10,7}
)开始,保持7的高度直到x=13(
{13,16}
),依此类推。内联注释应该可以很清楚地说明这里发生了什么,希望如此

我已经填充了矩形,留给您作为练习,要么只在数据中填充它们的开始和结束,要么只绘制 空空间旁边的矩形

您还必须更改输入

我认为我所做的和你所做的最大区别在于我对数据进行了几次不同的传递,第一次是计算每个矩形的宽度(使未来的计算更简单、更直观)和绘图的大小,第二次是在内存中填充绘图。请注意,我以相反的方式绘制它,然后首先绘制顶线,以简化绘制逻辑,但这是可以更改的。最后,我首先将数据绘制到内存中,然后在屏幕上绘制,这简化了在绘制星号之前要插入多少空格的逻辑

输出,以及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;
}
#包括
#包括
/*
而不是从上往下画,
将图像绘制成图形不是更容易吗
内存倒置,然后打印行
反过来?
*/
//假定该条带在下一条带开始时结束
//因此,可以预先计算宽度,这将
//显著简化显示逻辑。
类型定义结构{
无符号整数起始;
无符号整数高度;
无符号整数宽度;
}条状;
//为了简单起见,我假设这些是按
//起始位置。可以对它们进行分类以避免
//这一假设
int main(int argc,字符**argv){
//如果我们是
//采用动态输入
无符号整数striplen=8;
条带[]={
{ 0,  3, 0 },
{ 2, 10, 0 },
{ 5, 16, 0 },
{ 9,  7, 0 },
{ 11, 1, 0 },
{ 15,12, 0 },
{ 17, 6, 0 },
{ 20, 0, 0 }
};
//最后一条带的宽度为0,其高度必须为0才能“完成”该条带
//否则,我们实际上需要知道每条带的宽度(这将
//是一个更完整的数据模型,但我们可以在
//假设最后一条为0)
//我们将发现整个情节的“大小”
//并设置宽度
无符号整数绘图\u宽度=0;
无符号整数绘图高度=0;
无符号int laststart=0;
for(无符号整数i=0;i0){
//根据上一条带的宽度差异设置上一条带的宽度
//起始位置
条带[i-1]。宽度=条带[i]。开始-条带[i-1]。开始;
//现在我们可以将宽度添加到总宽度中
//最后一条的宽度和高度要求为0,
//我们不必担心最后一个宽度不是
//考虑到。
绘图宽度+=条带[i-1]。宽度;
}
}
//绘制填充的矩形,因为它更容易处理
//他们的十字路口在那边。
//当我们绘制它们时,我们可以使用内存中的绘图来决定
//星号是边还是填充
fprintf(标准,“绘图是%u乘以%u\n”,绘图宽度,绘图高度);
char*plot\u data=calloc(plot\u height*plot\u width,sizeof(char));
for(无符号整数i=0;i=0;y--){
对于(无符号整数x=0;x
以下是我的想法。内联注释应该可以很清楚地说明这里发生了什么,希望如此

我已经填充了矩形,留给您作为练习,要么只在数据中填充它们的开始和结束,要么只绘制 空空间旁边的矩形

您还必须更改输入

我认为我所做的和你所做的最大区别在于我对数据进行了几次不同的传递,第一次是计算每个矩形的宽度(使未来的计算更简单、更直观)和绘图的大小,第二次是在内存中填充绘图。请注意,我以相反的方式绘制它,然后首先绘制顶线,以简化绘制逻辑,但这是可以更改的。最后,我首先将数据绘制到内存中,然后在屏幕上绘制,这简化了在绘制星号之前要插入多少空格的逻辑

输出,以及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;
}
#包括
#包括
/*
而不是从上往下画,
这样做不是更容易吗