Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在c+中增加字母组合+;超越';z';?_C++_Excel_Char_Increment - Fatal编程技术网

C++ 如何在c+中增加字母组合+;超越';z';?

C++ 如何在c+中增加字母组合+;超越';z';?,c++,excel,char,increment,C++,Excel,Char,Increment,我正在做一个Excel电子表格,对于大量的数据,我只需要使用一种公式。因为在公式中,唯一必要的更改涉及字母,我想知道是否有一种方法可以使程序按照Excel列顺序(a、B、C…Z;AA、AB、AC…AZ;BA、BB、BC…BZ)递增字母 在我的例子中,我需要每次增加5个字母,因此下面是我试图获得的代码类型: #include <iostream> using namespace std; int main() { char x = 'B'; char y = 'E'; fo

我正在做一个Excel电子表格,对于大量的数据,我只需要使用一种公式。因为在公式中,唯一必要的更改涉及字母,我想知道是否有一种方法可以使程序按照Excel列顺序(a、B、C…Z;AA、AB、AC…AZ;BA、BB、BC…BZ)递增字母

在我的例子中,我需要每次增加5个字母,因此下面是我试图获得的代码类型:

#include <iostream>

using namespace std;

int main() {

 char x = 'B';
 char y = 'E';
 for (int z = 1; z < 2255; z++) {
   cout << "=SUMPRODUCT(SUBTOTAL(4,OFFSET(" << x << "1:" << y << "1,ROW(" << x << "1:" << x << "100)-ROW(" << x << "1),)))" << endl;
   x = x + 5;
   y= y + 5;
  }
  return 0;
}
#包括
使用名称空间std;
int main(){
char x='B';
chary='E';
对于(intz=1;z<2255;z++){
不能这样做:

x = (x + 5 > 'Z' ? x + 5 - 'Z' + 'A' : x + 5);
y = (y + 5 > 'Z' ? y + 5 - 'Z' + 'A' : y + 5);

您可以在两个嵌套循环中执行此操作,都是从
'A'
'Z'
,然后将这两个字符附加在一起。将结果放入向量中


要获取单个字母
'A'
'Z'
,请将它们添加到嵌套循环之前的向量中。

一般解决方案说明

解决方案1:创建base-26系统本身:

假设您有26个字母。首先让我们创建26个数字系统。我们为每个数字使用1个字节。我们创建一个数字数组,然后当相加超过26时,有时需要进行调整

假设您当前的数字是25。我们将其加上7,然后我们需要处理溢出,假设最大值为256(1字节),数字限制为26。因此调整值将为
256-26=230
(我们在短(16位)上进行此计算),因此我们在
26+7=33->33+230=263处出现溢出。因此,较高的字节将为1,较低的字节将为7。)

在计算了溢出阈值(高于1)之后,我们可以将其添加到下一个数字,如果发生溢出,也可以这样做

最后,为了显示,我们只需将65('A')添加到两个字节中的每一个。我们的最后一个字节将是'\0'null,以便将其转换为字符串

解决方案2执行所有计算,然后将其转换为26个基数:

在这种情况下,

number/26 = x

我们将r1存储为一个字节

x/26 = x1

我们将r2存储到下一个字节

x1/26 = x2


我们将r3存储到下一个字节。我们得到一个字符串
r3 r2 r1'\0'
,然后向每个字节添加65个“a”。

作为一个选项,您可以创建一个由两个字符组成的新数据类型(类似于
std::pair
并为此定义算术

但是,我认为继续使用
int
(或
unsigned int
)进行计数和算术会更简单,并定义一个函数
“to_col_heading
”,将整数转换为Excel的一个/两个字符的列标题:

#include <string>
#include <iostream>
#include <stdexcept>
#include <iterator>

/* This is the function that performs
   the transformation. */    
std::string to_col_heading(unsigned i)
{
  if (i > 26+26*26)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  char char1 = 'A' + (i / 26) - 1;
  char char2 = 'A' + (i % 26);

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1);
  else
    return std::string(&char1,&char1 + 1) + char2;
}

int main()
{
  std::ostream_iterator<std::string> out(std::cout,", ");
  for (unsigned i = 0 ; i < 26+26*26 ; i += 5)
    *out = to_col_heading(i);

  std::cout << std::endl;
  return 0;
}

最多支持3个(按字母顺序排列)对于列标题的数字,下面的函数起作用。它完全单独处理前26个值,以简化其余值的计算。我还引入了一些静态常数,以更一致的方式处理26的幂。对于三个数字,需要260、261和262,但系统可以扩展到任何数字of位数

我相信有一种方法可以优化速度;这不是本文的重点

std::string to_col_heading(unsigned i)
{
  const static unsigned pow1 = 26;
  const static unsigned pow2 = 26*26;
  const static unsigned max  = pow1 + pow2 + 26 * pow2;

  if (i < pow1)
    {
      char c = 'A' + i % pow1;
      return std::string(&c,&c+1);
    }

  if (i > max)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  i -= pow1;
  char char1 = 'A' + (i / pow2) - 1;
  char char2 = 'A' + (i%pow2) / pow1;
  char char3 = 'A' + i % pow1;

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1) + char3;
  else
    return std::string(&char1,&char1 + 1) + char2 + char3;
}
std::字符串到列标题(无符号i)
{
常量静态无符号pow1=26;
常量静态无符号pow2=26*26;
常量静态无符号最大值=pow1+pow2+26*pow2;
if(imax)
抛出标准::溢出错误
(“值太大,无法转换为Excel列标题。”);
i-=pow1;
charchar1='A'+(i/pow2)-1;
char char2='A'+(i%pow2)/pow1;
char char3='A'+i%pow1;
如果(第1章<'A')
返回std::string(&char2,&char2+1)+char3;
其他的
返回std::string(&char1,&char1+1)+char2+char3;
}

您尝试生成的结果可以被视为一个基数为27的数字,使用字符“a”到“Z”作为26位数字。这有点不寻常,因为“a”实际上是“0”,但当您得到一个两位数字时,它是“AA”,(正常的两位数是
BA
——也就是说,就像9后面的下一个数字是
10
)。我们必须做一个相当小的调整来弥补这个奇怪之处

您可以使用普通的
int
(或其他)进行计数,然后在需要时转换为基数27。由于我认为它支持的列数不超过此数,因此我将此版本限制为2位,但扩展到更多将非常简单:

std::string to_excel_column(int input) { 
    int digit1 = input % 26;
    int digit2 = input / 26;

    std::string result;
    if (input > 26)
        result.push_back(digit2 + 'A' - 1);
    result.push_back(digit1 + 'A');
    return result;
}

为什么格式不好?为什么要为普通文本加引号?我很乐意编辑此内容,但我想知道格式背后是否有任何意图。您可能希望查看标记源(通过单击
edit
而不实际编辑任何内容)看看它是如何工作的。谢谢你的回答。我需要3位数字,这个方法可行吗?因为我的最后一列是在字母“PQL”下面。是的,当然可以。同样的逻辑可以扩展到任意数量的字符。而且,很抱歉这个愚蠢的问题,为了做到这一点,应该在上面的代码中更改什么?@user2499266mented提供了一个支持三个字母数字的版本。但我只想说,我希望您不要滥用Stackoverflow作为代码编写服务。
#include <string>
#include <iostream>
#include <stdexcept>
#include <iterator>

/* This is the function that performs
   the transformation. */    
std::string to_col_heading(unsigned i)
{
  if (i > 26+26*26)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  char char1 = 'A' + (i / 26) - 1;
  char char2 = 'A' + (i % 26);

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1);
  else
    return std::string(&char1,&char1 + 1) + char2;
}

int main()
{
  std::ostream_iterator<std::string> out(std::cout,", ");
  for (unsigned i = 0 ; i < 26+26*26 ; i += 5)
    *out = to_col_heading(i);

  std::cout << std::endl;
  return 0;
}
A, F, K, P, U, Z, AE, AJ, AO, AT, AY, BD, BI, BN, BS, BX, CC, CH, CM, CR, CW, DB, DG, DL, DQ, DV, EA, EF, EK, EP, EU, EZ, FE, FJ, FO, FT, FY, GD, GI, GN, GS, GX, HC, HH, HM, HR, HW, IB, IG, IL, IQ, IV, JA, JF, JK, JP, JU, JZ, KE, KJ, KO, KT, KY, LD, LI, LN, LS, LX, MC, MH, MM, MR, MW, NB, NG, NL, NQ, NV, OA, OF, OK, OP, OU, OZ, PE, PJ, PO, PT, PY, QD, QI, QN, QS, QX, RC, RH, RM, RR, RW, SB, SG, SL, SQ, SV, TA, TF, TK, TP, TU, TZ, UE, UJ, UO, UT, UY, VD, VI, VN, VS, VX, WC, WH, WM, WR, WW, XB, XG, XL, XQ, XV, YA, YF, YK, YP, YU, YZ, ZE, ZJ, ZO, ZT, ZY,
std::string to_col_heading(unsigned i)
{
  const static unsigned pow1 = 26;
  const static unsigned pow2 = 26*26;
  const static unsigned max  = pow1 + pow2 + 26 * pow2;

  if (i < pow1)
    {
      char c = 'A' + i % pow1;
      return std::string(&c,&c+1);
    }

  if (i > max)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  i -= pow1;
  char char1 = 'A' + (i / pow2) - 1;
  char char2 = 'A' + (i%pow2) / pow1;
  char char3 = 'A' + i % pow1;

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1) + char3;
  else
    return std::string(&char1,&char1 + 1) + char2 + char3;
}
std::string to_excel_column(int input) { 
    int digit1 = input % 26;
    int digit2 = input / 26;

    std::string result;
    if (input > 26)
        result.push_back(digit2 + 'A' - 1);
    result.push_back(digit1 + 'A');
    return result;
}