帮助我理解和修复这个算法

Posted

技术标签:

【中文标题】帮助我理解和修复这个算法【英文标题】:Help me understand and fix this algorithm 【发布时间】:2009-11-16 05:35:14 【问题描述】:

我写了以下内容,但在对其进行了一些修改以适应单个像素(图形显示)而不是单个字符(字符显示)后,我不理解它。

XRES x YRES 是每个字符的像素分辨率。 LCDGraphic 根据这些值绘制自己的字符。这种转换算法的想法是,您可以向右、向左或(两者)向右移动一行,向左移动下一行,然后向右等...文本版本的工作方式与预期相同,但是当我将其翻译为图形显示,它的行为很奇怪。

LCOLS 是 256(哨兵),每次执行 LCDGraphic::Transition() 时,transition_tick_ 都会递增直到这个哨兵。 col 因此可以在 0-255 之间的范围内。好吧,当像素左右移动时,它们应该一起移动。但是,由于某种原因,向右移动的线条会一直移动到完成,然后向左移动的线条会一直移动到完成。似乎col< 128 的左侧移动线正在调整,然后当col>= 128 时右侧移动线调整。我对此感到很困惑。

void LCDGraphic::Transition() 
    int direction = visitor_->GetDirection();
    int col;
    transitioning_ = true;
    for(unsigned int row = 0; row < LROWS / YRES; row++) 
        if( direction == TRANSITION_LEFT ||
            (direction == TRANSITION_BOTH && row % 2 == 0))
            col = LCOLS - transition_tick_;
        else if( direction == TRANSITION_RIGHT || direction == TRANSITION_BOTH)
            col = transition_tick_;
        else
            col = 0;

        if(col < 0)
            col = 0;

        for(unsigned int i = 0; i < YRES; i++) 
            int n = row * YRES * LCOLS + i * LCOLS;
            for(unsigned int l = 0; l < 1; l++) // LAYERS; l++) 
                RGBA tmp[LCOLS];
                memcpy(tmp + XRES, GraphicFB[l] + n + col + XRES, (LCOLS - col) * sizeof(RGBA));
                for(unsigned j = 0; j < XRES; j++)
                        tmp[j] = NO_COL;
                memcpy(GraphicFB[l] + n + col, tmp, sizeof(RGBA) * (LCOLS - col));
            
            
    

    transition_tick_+=XRES;
    if( transition_tick_ >= (int)LCOLS ) 
        transitioning_ = false;
        transition_tick_ = 0;
        emit static_cast<LCDEvents *>(
            visitor_->GetWrapper())->_TransitionFinished();
    

    GraphicBlit(0, 0, LROWS, LCOLS);

【问题讨论】:

“我写了以下,但我不明白” - 如果你不明白,你怎么写? 我首先用 Python 编写了它,其中“列表”非常易于处理。我确实很幸运,弄明白了一点。一点点试错会有很长的路要走。 我从来不明白为什么第一个字符是空白的,不管它是向右还是向左。就像我说的,反复试验。我没想到它会做它所做的事情,当它刚刚起作用时,我就不管它了。我现在比那时更了解它,但是这个特殊的问题让我无所适从。我仍然不明白它为什么这样做。这是我作为程序员的弱点;我有计算障碍,有些问题超出了我的范围。我反复思考问题,最终得到它们。 你对这段代码应该做什么的描述对你来说可能很清楚,但对我们来说却很不清楚。 “这种转换算法的想法是,您可以向右、向左或(同时)向右走一行,向左走下一行,然后向右,等等……” 什么? 【参考方案1】:

我想通了。只有一半 LCOLS。奇怪的问题。我还是有点迷茫。

void LCDGraphic::Transition() 
    int direction = visitor_->GetDirection();
    int col;
    transitioning_ = true;
    for(unsigned int row = 0; row < LROWS / YRES; row++) 
        if( direction == TRANSITION_LEFT ||
            (direction == TRANSITION_BOTH && row % 2 == 0))
            col = LCOLS / 2 - transition_tick_; // changed this line
        else if( direction == TRANSITION_RIGHT || direction == TRANSITION_BOTH)
            col = transition_tick_;
        else
            col = 0;

        if(col < 0)
            col = 0;

        for(unsigned int i = 0; i < YRES; i++) 
            int n = row * YRES * LCOLS + i * LCOLS;
            for(unsigned int l = 0; l < 1; l++) // LAYERS; l++) 
                RGBA tmp[LCOLS];
                LCDError("Transition: LROWS: %u, LCOLS: %u, n: %d, row: %d, col: %d, calc1: %d, calc2: %d, fb: %p, tmp: %p",
                    LROWS, LCOLS, n, row, col, n + col + XRES, (LCOLS - col) * sizeof(RGBA), GraphicFB, tmp);
                memcpy(tmp + XRES, GraphicFB[l] + n + col + XRES, (LCOLS - col) * sizeof(RGBA));
                for(unsigned j = 0; j < XRES; j++)
                        tmp[j] = NO_COL;
                memcpy(GraphicFB[l] + n + col, tmp, sizeof(RGBA) * (LCOLS - col));
            
        
    

    transition_tick_+=XRES;
    if( transition_tick_ >= (int)LCOLS / 2)  //changed this line
        transitioning_ = false;
        transition_tick_ = 0;
        emit static_cast<LCDEvents *>(
            visitor_->GetWrapper())->_TransitionFinished();
    

    GraphicBlit(0, 0, LROWS, LCOLS);

【讨论】:

以上是关于帮助我理解和修复这个算法的主要内容,如果未能解决你的问题,请参考以下文章

失败了一个简单的HackerRank问题,没有在线学习的方法,请帮助我修复简单但错误的算法

有人可以帮助解释这个回溯算法中的递归吗?

深入理解Mysql索引底层数据结构与算法

关于SVM数学细节逻辑的个人理解 :SMO算法理解

模板强连通分量和tarjan算法

二值图像连通域标记算法优化