对称三进制数的对称即相反数的一致性,因此它就和二进制代码不同,不存在无符号数的概念。
在一般情况下,命题不一定为真或假,还可能为未知。在三进制逻辑学中,符号1代表真;符号-1代表假;符号0代表未知。
本文章中,为了方便表示,我们用符号’-'表示-1。
以下代码中,Ternary(int x)函数是算法的关键代码。
定义Ternary类:
class Ternary{
private:
char num[25];//数字位
//3^22=31,381,059,609刚好大于INT_MAX,所以22位够用,这里为了安全就填了25位。
public:
Ternary();
Ternary(int x);
void print();
};
将int型的x转化为Ternary类型的函数:
正数处理,从低位到高位不断对3取余,得0则该位为0,得1为1,得2为-1,然后减去得到的位值,将x地板除以3,重复以上操作直到遍历完所有位。
若x为负数,先把符号位存起来,然后将x变为正数处理,最后再将所有位取反。
Ternary(int x){
bool sgn;
if (x<0){
sgn = 1;//pos:0, neg:1
x = -x;
}else sgn = 0;
for (int i=0; i<=22; i++){
int rem = x%3;
if (rem == 2) num[i] = -1;
else num[i] = rem;
x -= num[i];
x /= 3;
}
if (sgn) for (int i=0;i<=22;i++) num[i] = -num[i];
}
打印函数:
从高位到低位打印即可
要去除前导0所以用了bool变量fnzn。
putchar时若为-1打印‘-’。
void print(){
bool fnzn = false;//是否出现了first non-zero number
for (int i=22;i>0;i--){
if (num[i]){
fnzn = true;
putchar(num[i]==-1?'-':num[i]+'0');
}else if (fnzn) putchar(num[i]==-1?'-':num[i]+'0');
}
putchar(num[0]==-1?'-':num[0]+'0');//最低位必打印,所以特殊处理
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
class Ternary{
private:
char num[25];//数字位
public:
Ternary(){
memset(num,0,sizeof(num));
}
Ternary(int x){
bool sgn;
if (x<0){
sgn = 1;//pos:0, neg:1
x = -x;
}else sgn = 0;
for (int i=0; i<=22; i++){
int rem = x%3;
if (rem == 2) num[i] = -1;
else num[i] = rem;
x -= num[i];
x /= 3;
}
if (sgn) for (int i=0;i<=22;i++) num[i] = -num[i];
}
void print(){
bool fnzn = false;//是否出现了first non-zero number
for (int i=22;i>0;i--){
if (num[i]){
fnzn = true;
putchar(num[i]==-1?'-':num[i]+'0');
}else if (fnzn) putchar(num[i]==-1?'-':num[i]+'0');
}
putchar(num[0]==-1?'-':num[0]+'0');//最低位必打印,所以特殊处理
}
};
int n;
int main(){
scanf("%d",&n);
while (n--){
int x;
scanf("%d",&x);
Ternary(x).print();
putchar('\n');
}
return 0;
}
以下是样例运行结果,左列为原数,右列为转化后的对称三进制数。
-5 -11
-4 --
-3 -0
-2 -1
-1 -
0 0
1 1
2 1-
3 10
4 11
5 1--
6 1-0
7 1-1
8 10-
9 100
10 101
11 11-
12 110
13 111
14 1---
15 1--0
知网一查,已经有人做过这方面的算法研究了,故本人的研究到此为止,有兴趣的同学想进一步了解可以看看他们的论文。