我正在将整数值转换为三元数(即字符串)。我怀疑应该有一种更好的方法来实现这一点,只需较少的计算工作量。
我的算法直接实现了长除法,可以在十进制和任意基数之间转换数字。
char *get_ternary_str(int value) {
char buffer[3] = { "000" };
int dividend = value;
int i = 0;
do {
int remainder = dividend % 3;
dividend = dividend / 3;
buffer[i] = ((char)remainder + '0');
i++;
} while(dividend >= 1 && i < 3);
char temp = buffer[2];
buffer[2] = buffer[0];
buffer[0] = temp;
return buffer;
}
即使在这个例子中,三元数是3位长,我的目标是使它成为n位长。也欢迎就如何对n位三元数执行此操作提出建议。
如果您关心的是计算时间,您可以使用一个简单而小的查找表来交换一些内存空间。
把这个C(你的问题的早期版本也是用这种语言提出想法的)片段作为我提出的算法的一个例子。
#include <iostream>
#include <array>
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm>
#include <limits>
std::string ternary_from(int value)
{
// The idea is to elaborate three figures (in base 3) at a time
constexpr int dim = 3 * 3 * 3;
// Note the values, are "reversed"
static const std::array<std::string, dim> inner_parts {
"000", "100", "200", "010", "110", "210", "020", "120", "220",
"001", "101", "201", "011", "111", "211", "021", "121", "221",
"002", "102", "202", "012", "112", "212", "022", "122", "222"
};
static const std::array<std::string, dim> parts {
"", "1", "2", "01", "11", "21", "02", "12", "22",
"001", "101", "201", "011", "111", "211", "021", "121", "221",
"002", "102", "202", "012", "112", "212", "022", "122", "222"
};
if ( value == 0 )
return std::string{"0"};
std::string result;
// Thanks @Chux for recalling that -INT_MIN is UB
unsigned tmp = value;
if ( value < 0 )
tmp = -tmp;
// note that 'dim' = 27, so you are performing a third of the calculations
while (tmp >= dim)
{
unsigned remainder = tmp % dim;
// concatenating a string at the end is easier...
result += inner_parts[remainder];
tmp = tmp / dim;
}
result += parts[tmp];
if (value < 0)
result += '-';
// now the string needs to be reversed. e.g. 3 -> 10(3), not 01
std::reverse(result.begin(), result.end());
return result;
}
int main()
{
std::vector<int> tests {
42, -8, 0, 81, 27, -28, std::numeric_limits<int>::max(), std::numeric_limits<int>::min()
};
std::cout << " decimal ternary\n";
for (int i : tests)
{
std::cout << std::setw(12) << i << std::setw(23) << ternary_from(i) << '\n';
}
}
It输出
decimal ternary 42 1120 -8 -22 0 0 81 10000 27 1000 -28 -1001 2147483647 12112122212110202101 -2147483648 -12112122212110202102
代码有问题。
返回指向局部变量的指针
返回指向本地(非静态)变量的指针是未定义行为(UB)。不要依赖该内存在函数完成后有效。
char *get_ternary_str(int value) {
char buffer[3] = ...
...
return buffer; // UB
}
以负数失败
-1%3
--
int remainder = dividend % 3;
...
buffer[i] = ((char)remainder + '0');
空间不足
缓冲区[3]对于字符串“000”来说太小,因为空字符需要空间<代码>缓冲区[3]对于一个3位字符的数组来说足够大,但肯定需要一个字符串。
// char buffer[3] = { "000" };
char buffer[3+1] = { "000" };
从未分配过空字符
当然,结果应该是需要空字符“\0”的字符串。为了确保这一点,需要对法规进行修订。
我的目标是使其具有n位数的长度,也欢迎您就如何对n位数的三元数执行此操作提出建议。
需要一个char缓冲区来处理形成的字符串。一个简单的解决方案是传入一个足够大的缓冲区指针,以应对最坏的情况。我建议也传入缓冲区的大小。
下面是处理任意基数2-36的解决方案。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Maximum buffer size (worst case: INT_MIN and base 2)
#define ITOA_BASE_N (1 + sizeof(int)*CHAR_BIT + 1)
char *itoa_base(char *dest, size_t sz, int i, unsigned base) {
char buf[ITOA_BASE_N];
char *s = &buf[sizeof buf - 1]; // set to last character.
*s = '\0';
unsigned u = (unsigned) i; // Use unsigned to cope with INT_MIN ...
if (i < 0) {
u = -u; // ... as -INT_MIN is UB
}
do {
*(--s) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[u % base];
u /= base;
} while (u);
if (i < 0) {
*(--s) = '-';
}
size_t size_used = &buf[sizeof buf] - s;
if (size_used > sz) {
return NULL; // or some other error handling.
}
return memcpy(dest, s, size_used);
}
该测试使用复合文本进行临时存储,但如果需要,可以传入固定缓冲区。
#define TO_BASE3(x) itoa_base((char [ITOA_BASE_N]){0}, ITOA_BASE_N, (x), 3)
void test3(int x) {
char *s = TO_BASE3(x);
// do stuff with `s`, it is valid for until the end of this block
printf("base10:%11d base3:'%s'\n", x, s);
}
int main(void) {
test3(0);
test3(1);
test3(42);
test3(-81);
test3(INT_MAX);
test3(INT_MIN);
}
输出
base10: 0 base3:'0'
base10: 1 base3:'1'
base10: 42 base3:'1120'
base10: -81 base3:'-10000'
base10: 2147483647 base3:'12112122212110202101'
base10:-2147483648 base3:'-12112122212110202102'
因为您需要建议,所以我不提供代码。但是,如果您需要进一步的帮助,您可以在评论中指出。
我可以运行这个程序,但由于某些原因,它会显示/放置随机字符,而不是二进制的初始值,而且我似乎无法将程序从十进制运行回二进制。我该如何改进这些代码。要明确说明它不会将二进制转换为十进制,我将如何将其转换回十进制转换为二进制,如果有一些代码可以帮助我,将不胜感激。
本文向大家介绍十进制到二进制转换,包括了十进制到二进制转换的使用技巧和注意事项,需要的朋友参考一下 十进制数字也可以转换为二进制格式。要将十进制数转换为二进制数,我们需要将数字除以2,直到达到0或1。然后,在每一步骤中,其余部分将分开存储以形成相反的二进制等效数。 在此算法中,我们将遵循递归方法。这将帮助我们在不使用堆栈数据结构的情况下解决问题。在实现中,我们知道函数的递归将遵循内部堆栈。我们将使
问题内容: 我有一个家庭作业,需要在十进制,二进制和十六进制之间进行三向转换。我需要帮助的功能是将十进制转换为十六进制。我几乎不了解十六进制,但是如何将十进制转换为十六进制。我需要一个接受并返回的函数。不幸的是我没有此功能的任何草稿,我完全迷路了。我只有这个。 另外,我不能使用诸如Integer.toHexString()之类的预制函数或任何其他东西,我需要真正地制作算法,否则我什么都不会学。 问
Python3 实例 以下代码用于实现十进制转二进制、八进制、十六进制: # -*- coding: UTF-8 -*- # Filename : test.py # author by : www.runoob.com # 获取用户输入十进制数 dec = int(input("输入数字:")) print("十进制数为:", dec) print("转换为二进制为:", bin(dec
本文向大家介绍科学知识:二进制、八进制、十进制、十六进制转换,包括了科学知识:二进制、八进制、十进制、十六进制转换的使用技巧和注意事项,需要的朋友参考一下 一、 十进制与二进制之间的转换 (1) 十进制转换为二进制,分为整数部分和小数部分 ① 整数部分 方法:除2取余,逆序排列,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为
问题内容: 我试图在python函数中使三进制十进制数。我的想法是继续除法,直到商和余数相等,但是我似乎无法使它起作用。这是我的代码: 问题答案: 我的想法是继续除法,直到商和余数相等,但是我似乎无法使它起作用。 是的,类似的东西。本质上,您希望保持除以3,然后收集余数。其余的则组成最终的数字。在Python中,您可以用来划分和收集余数。 例子: