判断一个自然数是否是某个数的平方。当然不能使用开方运算—谷歌

本文介绍了三种判断一个自然数是否为另一个数的平方的方法,包括遍历比较、二分查找及利用等差数列特性的方式,并提供了一段C++实现代码。
 

判断一个自然数是否是某个数的平方。当然不能使用开方运算—谷歌

分类: 微软、谷歌、百度等公司经典面试100题_2011   921人阅读  评论(0)  收藏  举报
假设待判断的数字是 N。

方法1:
遍历从1到N的数字,求取平方并和N进行比较。
如果平方小于N,则继续遍历;如果等于N,则成功退出;如果大于N,则失败退出。
复杂度为O(n^0.5)。

方法2:
使用二分查找法,对1到N之间的数字进行判断。
复杂度为O(log n)。

方法3:
由于
(n+1)^2 
=n^2 + 2n + 1,
= ...
= 1 + (2*1 + 1) + (2*2 + 1) + ... + (2*n + 1)

注意到这些项构成了等差数列(每项之间相差2)。

 由于N = 1 + (2 + 1) + ( 4 + 1) + ( 6 + 1) + ....

所以我们可以比较 N-1, N - 1 - 3, N - 1 - 3 - 5 ... 和0的关系。
如果大于0,则继续减;如果等于0,则成功退出;如果小于 0,则失败退出。
复杂度为O(n^0.5)。不过方法3中利用加减法替换掉了方法1中的乘法,所以速度会更快些。

转自:http://hi.baidu.com/mianshiti/blog/item/6b27b2edd1734b252df5348b.html


c++代码:
#include <iostream>
using namespace std;

bool check(int n, int &result)
{
    int temp = 1, i;
    for(i=1; i<n; i++) {
        n -= temp;
        if(n < 0) return false;
        else if(n == 0) {
            result = i;
            return true;
        }
        temp += 2;
    }
    return false;
}

int main()
{
    int number, res;
    cin >> number;
    if(check(number, res))
        cout << number << " is " << res << "^2" << endl;
    else
        cout << number << " isn't n^2" << endl;
    return 0;
}

output:
64
64 is 8^2

-23
-23 isn't n^2

0
0 isn't n^2
<think>首先,用户的问题是:"我想使用C语言编写一个判断一个自然数是否包含字5"。用户提到了站内引用,但引用内容主要是关于判断和递归函的,没有直接与判断字5相关的。所以,我需要专注于用户的核心需求。 用户要求使用C语言编写一个判断一个自然数是否包含字5。这意味着函应该接受一个,返回一个布尔值(或整)表示字5是否存在于该的任何位上。 关键点: - 输入:一个自然数(正整)。 - 输出:真(1)或假(0),表示该是否包含字5。 我需要设计一个: - 函名:例如,containsDigitFive 或类似的。 - 参:整 n。 - 返回值:1 如果 n 包含字5,否则 0。 实现思路: - 要检查一个的每一位是否等于5。 - 由于字可能有多位,我需要遍历每一位。 - 可以通过循环来处理: - 使用运算符 (%) 来获取最后一位字。 - 检查该是否等于5。 - 如果是,返回真。 - 否则,将字除以10去掉最后一位。 - 重复直到字变为0。 - 边界情况:如果输入是0,它不包含5,所以返回0。 - 负:用户指定了自然数,所以应该只考虑正整。假设输入为正整。 函原型: ```c int containsDigitFive(int n); ``` 在C语言中,我们通常用int返回1或0来表示真假。 现在,参考用户提供的引用: - 引用[1]提到素判断,但不相关。 - 引用[2]是判断的函,展示了循环遍历。 - 引用[3]是递归函判断字的低位部分。 引用[3]特别相关,因为它涉及递归地检查字的每一位。用户的问题可以类似地用递归或迭代解决。 我可以用迭代方法: 1. 如果n为0,返回0(因为没有字)。 2. 当n不为0时: - 取最后一位:digit = n % 10 - 如果digit == 5,返回1 - 否则,n = n / 10 3. 如果循环结束还没有返回1,返回0。 递归方法: - 类似于引用[3],但检查字5。 - 基本情况:如果n == 0,返回0(假)。 - 递归步:检查n % 10 == 5,如果是,返回1;否则,递归调用containsDigitFive(n / 10)。 迭代可能更高效,因为递归有栈开销。 用户上一次问题是关于判断的,但现在是判断字5,所以我应该直接回答这个。 系统指令要求: - 使用中文回答。 - 结构清晰。 - 生成相关问题。 - 添加引用标识(但这里引用不直接相关,所以可能不需要)。 - 代码使用正确语法。 回答结构: 1. 解释思路。 2. 提供函代码。 3. 解释代码。 4. 生成相关问题。 代码格式:使用代码块。 最终函: ```c int containsDigitFive(int n) { if (n < 0) { // 处理负,但自然数通常非负,假设输入正整 n = -n; // 取绝对值,以防万一 } while (n > 0) { int digit = n % 10; if (digit == 5) { return 1; } n = n / 10; } return 0; } ``` 考虑到自然数可能是0,但0不包含5,所以返回0是正确的。 如果n为0: - n % 10 = 0,不等于5。 - n / 10 = 0,循环结束,返回0。正确。 现在,中文回答: - 开头:解释函目的。 - 提供代码。 - 解释关键步骤。 - 结束生成相关问题。 相关问题: 1. 如何判断一个是否包含其他特定字? 2. 如何计算一个字5出现的次? 3. 如何判断一个是否由特定字组成? 4. 递归版本的实现? 5. 在C语言中如何处理大字检查? 确保回答可靠。 </think>### 判断自然数是否包含字5的函(C语言实现) 您需要使用C语言编写一个判断一个自然数(正整是否包含字5。核心思路是通过循环遍历该的每一位字,检查是否有任何一位等于5。以下是完整的实现: ```c #include <stdio.h> // 包含标准输入输出库(可选,便于演示) // 判断自然数是否包含字5的函 // 参:n - 输入的自然数(正整) // 返回值:1 - 包含字5;0 - 不包含字5 int containsDigitFive(int n) { // 处理n=0的特殊情况(0不包含任何字) if (n == 0) { return 0; } while (n > 0) { // 当n > 0时继续循环 int digit = n % 10; // 获取最后一位字 if (digit == 5) { // 如果该位字等于5 return 1; // 立即返回true(1) } n = n / 10; // 移除最后一位(整除法) } return 0; // 所有位遍历完毕,未找到5,返回false(0) } // 演示示例(可选) int main() { int num = 12345; if (containsDigitFive(num)) { printf("%d 包含字5\n", num); } else { printf("%d 不包含字5\n", num); } return 0; } ``` #### 代码解释: 1. **函逻辑**: - 使用 `while (n > 0)` 循环遍历字的每一位。 - `n % 10` 获取当前最后一位字(例如 `12345 % 10 = 5`)。 - 如果该位等于5,立即返回1(真)。 - 否则,通过 `n = n / 10` 移除最后一位(例如 `12345 / 10 = 1234`)。 - 如果循环结束未找到5,返回0(假)。 2. **边界处理**: - 输入为0时直接返回0(因为0没有字位)。 - 自然数定义为正整,因此无需处理负。如果输入负可能导致无限循环,建议调用前确保输入为正整 [^2]。 3. **性能**: - 时间复杂度为 $O(d)$,其中 $d$ 是字的位(例如12345有5位)。该方法高效可靠,适合所有自然数。 #### 示例测试: - `containsDigitFive(123)` → 返回0(不包含5) - `containsDigitFive(506)` → 返回1(包含5) 如果您需要递归版本(类似引用[3]的风格),我可以补充提供。同时,参考中提到的素判断逻辑(引用[1][^1])不直接适用于此问题,但字操作技巧有共通之处。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值