判断一个数在2-16进制下是否为回文 Palindrom Numbers

验证任意数值在2到16进制下是否为回文数
此博客探讨如何识别一个整数在不同进制下是否为回文数,即从左到右读取与从右到左读取相同。通过编程实现这一功能,对于每个输入的整数,输出其在哪些进制下为回文数,若在所有指定进制下都不是,则输出该整数不是回文数。

Statement of the Problem

We say that a number is a palindrom if it is the sane when read from left to right or from right to left. For example, the number 75457 is a palindrom.

Of course, the property depends on the basis in which is number is represented. The number 17 is not a palindrom in base 10, but its representation in base 2 (10001) is a palindrom.

The objective of this problem is to verify if a set of given numbers are palindroms in any basis from 2 to 16.

Input Format

Several integer numbers comprise the input. Each number 0 < n < 50000 is given in decimal basis in a separate line. The input ends with a zero.

Output Format

Your program must print the message Number i is palindrom in basis where I is the given number, followed by the basis where the representation of the number is a palindrom. If the number is not a palindrom in any basis between 2 and 16, your program must print the message Number i is not palindrom.

Sample Input

17
19
0

Sample Output

Number 17 is palindrom in basis 2 4 16
Number 19 is not a palindrom


//============================================================================
// Name        : 算法.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

int main() {
	int x;

	cin >> x;

	while(x){
		bool isPali = false;
		char arr[30];
		int base[17] = {0};
		for(int i=2; i<=16; i++){

			int temp = x;
			int len = 0;
			while(temp){
				arr[len++] = temp % i;
				temp /= i;
			}
			bool tag = true;
			/*for(int j=0,k=len-1; j<k; j++,k--){
				if(arr[j] != arr[k]){
					tag = false;
					break;
				}
			}*/
			//第二种写法
			for(int j=0; j<len/2 && tag; j++)
				if(arr[j] != arr[len-j-1])
					tag = false;
			if(tag){
				base[i] = 1;
				isPali = true;
			}
		}

		if(!isPali)
			cout << "Number "<< x <<" is not a palindrom" << endl;
		else{
			cout << "Number "<< x <<"is palindrom in basis at:";
			for(int i=2; i<=16; i++){
				if(base[i])
					cout <<i << " ";
			}
		}

		cin >> x;
	}
	return 0;
}




<think>题目要求:判断一个正整的二进制表示是否回文,且不能使用组存储二进制位。思路:1.我们可以通过位操作来分别获取整的最高位和最低位进行比较。2.但是,如果我们不知道整的位,我们可以先计算整的总位(即二进制)。3.然后,我们从两端(最左边和最右边)开始逐位比较,直到中间。具体步骤:步骤1:计算整n的二进制(记为bits)。我们可以通过不断右移直到n为0,来统计位。步骤2:设置两个指针,一个指向最左边(最高位),一个指向最右边(最低位)。左边位:可以通过将1左移(bits-1)位,然后与n进行与运算,判断该位是否为1。右边位:直接与1进行与运算,判断最低位是否为1。步骤3:比较左右两边的位,如果不相等,则不是回文;如果相等,则继续向中间移动。步骤4:每次比较后,去掉已经比较过的最高位和最低位(可以通过掩码和移位实现),然后更新位(因为去掉了两位,所以位减少2)?或者我们可以通过移动指针来实现。但是,注意:去掉最高位后,剩下的位会少一位,而最低位去掉后,剩下的右移一位即可。同时,我们也可以不实际去掉最高位,而是通过调整掩码来改变最高位的位置。另一种思路(推荐):我们可以同时从两边向中间比较,而不实际修改n的值。我们可以用两个变量来记录当前比较的左右位置。具体:left_mask=1<<(bits-1)//最高位的掩码right_mask=1//最低位的掩码whileleft_mask>right_mask:比较n在left_mask位置上的位和right_mask位置上的位是否相同:不相同则返回false然后,left_mask右移一位,right_mask左移一位,继续比较。但是,注意:我们每次比较两个位,然后移动掩码直到两个掩码交叉(即left_mask小于right_mask)或者相遇。然而,我们也可以这样:foriinrange(0,bits//2):left_bit=n&(1<<(bits-1-i))right_bit=n&(1<<i)#注意:left_bit和right_bit的值可能不相等,因为一个是高位一个是低位,我们需要将它们的值移到同一个位置比较,或者直接比较它们是否为0(非0则位为1,0则位为0)?#但是,不能直接比较值,因为两个位所在的位置不同,值也不同。例如,高位是1<<k,低位是1<<j,如果k!=j,那么值肯定不同。#所以,我们需要将两个位都移到最右边(通过右移),或者判断两个位是否同时为0或同时非0。实际上,我们可以这样判断:left_bit=(n>>(bits-1-i))&1#将当前最高位移到最低位,然后与1得到该位的值(0或1)right_bit=(n>>i)&1#将当前最低位移到最低位,然后与1得到该位的值(0或1)然后比较left_bit和right_bit是否相等。步骤:1.计算二进制bits。2.循环i从0到bits//2-1:left_bit=(n>>(bits-1-i))&1right_bit=(n>>i)&1ifleft_bit!=right_bit:returnFalse3.循环结束,说明是回文,返回True。注意:当n为0时,bits为0(但题目是正整,所以n>=1),所以不用担心0的情况。例子:n=5,二进制为101,bits=3i=0:left_bit:取第3-1-0=2位(即最高位,从左第0位?注意:我们通常从0开始编号,最高位是第2位(因为一共3位,从0到2)),实际上是取第2位(最左边是第2位,最右边是第0位)。(n>>2)&1:5的二进制是101,右移2位得到1,然后&1=1。right_bit:取第0位(i=0),(n>>0)&1=5的二进制最低位是1(101),所以是1。相等。i=1:left_bit:取第3-1-1=1位,即中间位。将n右移1位:101>>1=10(二进制),然后&1=0。right_bit:取第1位,将n右移1位:101>>1=10,然后&1=0?实际上,我们想要的是中间位?不对,我们的循环只进行到bits//2,即3//2=1,所以只有一次循环?因为3//2=1(整除法),所以循环i=0一次就够了。所以,对于奇位,中间位不需要比较。因此,这个方法是可行的。代码实现:注意:计算二进制bits:bits=0temp=nwhiletemp:bits+=1temp=temp>>1但是,注意:如果n=0,但是题目是正整,所以不需要考虑0。但是,有一个特殊情况:当n=1时,二进制为1,bits=1,循环次为0(因为1//2=0),所以直接返回True,正确。所以,我们可以写出如下代码:但是,题目要求不使用组存储二进制位,这里我们并没有使用组,所以符合要求。优化:我们可以不用循环计算位,使用内置函?但题目没有说,我们可以自己实现。另一种优化:我们可以用对,但是对可能不精确,所以还是用循环移位。代码:</think>### 判断进制回文解决方案 要判断一个正整的二进制表示是否回文,我们可以通过位操作直接比较二进制的对称位,无需存储整个二进制序列。以下是详细实现思路和代码: #### 实现思路 1. **计算二进制**:通过右移操作统计字的二进制 2. **比较对称位**: - 使用两个指针分别指向最高位和最低位 - 通过右移操作将目标位移到最低位,用`& 1`获取位的值 - 比较对称位置的位值是否相同 3. **终止条件**:当左指针越过右指针时停止比较 #### Python实现代码 ```python def is_binary_palindrome(n): # 计算二进制 temp = n bits = 0 while temp: bits += 1 temp >>= 1 # 比较对称位 left = bits - 1 # 最高位索引 right = 0 # 最低位索引 while left > right: # 获取最高位的值 high_bit = (n >> left) & 1 # 获取最低位的值 low_bit = (n >> right) & 1 if high_bit != low_bit: return False left -= 1 right += 1 return True # 测试示例 print(is_binary_palindrome(5)) # 输出: True (101) print(is_binary_palindrome(10)) # 输出: False (1010) print(is_binary_palindrome(9)) # 输出: True (1001) print(is_binary_palindrome(1)) # 输出: True (1) ``` #### 代码解释 1. **位计算**: - `while temp:` 循环通过右移`temp >>= 1`统计二进制 - 例如:5(101)→ bits=3 2. **对称位比较**: - `(n >> left) & 1`:将目标位移到最低位后取位值 - 指针移动:`left`从高位向低位移动,`right`从低位向高位移动 - 比较过程(以5为例): - 初始:left=2, right=0 - 第1轮:比较第2位(1)和第0位(1) → 相等 -2轮:left=1, right=1 → 循环终止(奇的中间位无需比较) 3. **边界处理**: - 当n=1时:bits=1,直接返回True - 当n=0时:题目要求正整,无需特殊处理 #### 复杂度分析 - **时间复杂度**:O(b),b为二进制(循环次 = b/2- **空间复杂度**:O(1)(仅用常级额外空间) 这种方法直接通过位运算完成比较,无需额外存储空间,完全符合题目要求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值