【问题标题】:Accounting for no existant characters as inputs C将不存在的字符作为输入 C
【发布时间】:2015-11-01 09:36:40
【问题描述】:

对不起,如果问题的标题有点偏离,我不知道该怎么称呼它,因为它是一个如此特殊的问题。我的目标是将使用我稍后将解释的方法编码的输入字符串解码为纯英文文本。 编码是通过选择一个介于 2 到消息长度一半之间的整数 nRows 来完成的,例如长度为 11 的消息将允许 nRows 的值在 2 到 5 的范围内。然后将消息写入网格的列,每个网格单元格中有一个字符,每列中有 nRows,直到使用完所有消息字符。这可能会导致最后一列仅被部分填充。然后逐行读出消息。 例如,如果输入消息是 ALL HAIL CAESAR,并且 nRows 值为 2,则编码将如下所示:

A L H I   A S R
L   A L C E A @

@ 表示表格中的一个或空白字符,实际上并不存在 - 我只是添加它来解释下一部分:)

我的实际问题是解码这些短语。到目前为止,我编写的代码可以解决一些问题,但是一旦空白字符 (@) 变得很多,代码就会开始崩溃,因为代码显然没有注册它们并且算法会跳过它们。 我的代码是:

/*
 * DeConfabulons.c
 * A program to Decode for the Confabulons
 * 
 * August 9th 2015
 */

#include <stdio.h>
#include <string.h>
#include <math.h>

//A simple function confab which given input text encoded using
//the Confabulons encoding scheme, and a number of rows, returns 
//the originally encoded phrase.

void deconfab(const char inText[], int nRows, char outText[])
{
    int count = 0;
    int i = 0;
    int len = strlen(inText);
    float help = ((float)len/(float)nRows);
    int z = 0;
    while (z < round(help))
    {
        while (((int)inText[count] > 0) && (count <= len))
        {
            outText[i] = inText[count]; 
            i ++;
            if (count < (int)help)
            {
                count = count + round((int)help+0.5);
            }
            else
            {
                float helper = count + help;
                count = round(helper);
            }  


        }
        z ++;
        count = z;
    }
    outText[i] = '\0';
}

到目前为止,这适用于我之前给出的凯撒示例。它的编码形式是 ALHI ASRL ALCEA。我为该问题提供的主要(无效)输入是:

char buffer[40] = {'\0'};
deconfab("ALHI ASRL ALCEA", 2, buffer);
printf("%s\n", buffer);

正确输出:

ALL HAIL CAESAR

但是,在处理带有额外“空白”字符的案例时,例如:

char buffer[60] = {0};
char* s = "Two hnvde eo frgqo .uxti hcjeku  mlbparszo y";
deconfab(s, 13, buffer);
printf("%s\n", buffer);

输出应该是:

The quick brown fox jumps over the lazy dog.

但是我的代码会返回:

Thdefq.the browneorouickmps ov  g x julazy

通过手动运行多次测试,我得出结论,这是由最后一列末尾的空白字符引起的,但是无论我尝试什么,代码都不适用于每个测试用例。我可以以几乎任何方式编辑函数的大部分内容,但是不允许编辑 int main(void) 中的任何输入或任何内容。 我只是在寻找一种将这些空白字符识别为字符而不实际存在的方法(因此):)

【问题讨论】:

  • "但是,当处理带有额外空字符的案例时" 我在这里看不到那些额外的空字符 ""两个 hnvde eo frgqo .uxti hcjeku mlbparszo y “”
  • 我遇到的问题是它们实际上并不存在 - 如果您查看表格(第一个代码样式输入),字符是从列的顶部到底部读取的,从左到右.我使用的方法要求我们知道表格中有所有这些空格才能找到下一个字符。提供的输入不包含这些,我们希望以另一种方式解释它们。输入是从左到右从上到下跨行读取的(减去空白@单元格)我可能不应该事后称它们为 null,我现在会改变它

标签: c output decoding


【解决方案1】:

索引计算有些混乱。 起初它是纯粹的离散变换。因此,它应该只使用整数来实现。 下面的函数可以满足您的需要。

void deconfab(const char inText[], int nRows, char outText[])
{
    int len = strlen(inText);
    int cols = len / nRows;
    int rows_with_large_cols = len % nRows;
    int count = 0;
    int col = 0;
    int row = 0;

    while (count < len)
    {
        int idx;
        if (row < rows_with_large_cols)
            idx = row * (cols + 1) + col;
        else
            idx = rows_with_large_cols * (cols + 1) +
                (row - rows_with_large_cols) * cols + col;

        if (idx > len - 1) {
            ++col;
            row = 0;
            idx = col;
        }

        outText[count] = inText[idx];
        ++row;
        ++count;
    }
    outText[count] = '\0';
}

它可能会被重写得更好。现在它就像一个伪代码来解释算法。

【讨论】:

    【解决方案2】:

    首先,据我所知,您没有在输入中包含那些“空”字符 - 如果您这样做(我猜)通过添加任何“虚拟”字符,算法将起作用。在第一种情况下这样做的原因是输入末尾缺少“空白”字符 - 与句子中缺少的位置相同。

    您可以尝试通过使用这些虚拟字符(我不确定如何表述)来猜测消息的长度来解决问题,例如: ALHI ASRL ALCEA 有 15 个字符(15 mod 2 = 1),但 ALHI ASRL ALCEA@ 有 16 个字符。同样,Two hnvde eo frgqo .uxti hcjeku mlbparszo y 有 44 个字符 (44 mod 13 = 5),因此您需要相当多的虚拟字符才能完成这项工作 (13-5=8)。

    此时有几种方法 - 例如,您可以尝试插入缺少的空格以对齐列,将所有内容逐个字符复制到二维数组中,然后逐行读取,或者只是确定最后一列的 (len mod rows) 字符,从输入中删除它们(需要一些经典的 C 字符串函数,所以我不会在这里给你完整的答案),阅读其余部分,然后附加字符最后一栏。

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      如果要处理空值,则不能使用标准的 str* 函数。相反,您必须直接处理数据并使用*read 系列函数来获取数据。

      【讨论】:

        猜你喜欢
        • 2021-08-17
        • 2016-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多