📌  相关文章
📜  C++程序最小化要更改的字符以使字符串的左右旋转相同(1)

📅  最后修改于: 2023-12-03 15:14:04.696000             🧑  作者: Mango

C++程序最小化要更改的字符以使字符串的左右旋转相同

在本文中,我们将探讨一种技术,即最小化要更改的字符以使字符串的左右旋转相同的问题。这是一个很有趣和有用的问题,它涉及到了字符串和算法的知识。

问题描述

给定一个字符串,我们可以任意旋转它。例如,字符串 "abcde" 可以旋转为 "bcdea"、"cdeab"、"deabc"、"eabcd" 和 "abcde"。但旋转后的字符串可能与原始字符串不同,因此我们需要找出最小化要更改的字符的数量,以使字符串的左右旋转相同。

例如,对于字符串 "abcde",我们可以将其旋转为 "bcdea",在这种情况下,我们只需要更改一个字符 'a' 为 'b' 即可。因此,答案为 1。

解决方案

要解决这个问题,我们需要执行以下步骤:

  1. 计算字符串的哈希值。

  2. 枚举旋转的位置,计算新的字符串的哈希值。

  3. 如果新的字符串的哈希值与旧的字符串的哈希值相同,则说明旋转后的字符串与原始字符串相同。

  4. 计算最小更改字符的数量。

下面是一个C++程序的大致实现:

#include <iostream>
#include <vector>

using namespace std;

// 计算字符串的哈希值
unsigned long long hash_string(const string& s)
{
    const unsigned long long p = 31;
    const unsigned long long m = 1e9 + 9;
    unsigned long long hash_value = 0;
    unsigned long long p_pow = 1;
    for (char c : s) {
        hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m;
        p_pow = (p_pow * p) % m;
    }
    return hash_value;
}

// 计算最小更改字符的数量
int min_changes(const string& s)
{
    int n = s.size();
    string t = s + s;
    unsigned long long hash_value = hash_string(s);
    vector<unsigned long long> hashes(n + 1);
    hashes[0] = 0;
    const unsigned long long p = 31;
    const unsigned long long m = 1e9 + 9;
    unsigned long long p_pow = 1;
    for (int i = 0; i < n; ++i) {
        hashes[i + 1] = (hashes[i] + (t[i] - 'a' + 1) * p_pow) % m;
        p_pow = (p_pow * p) % m;
    }
    int ans = n;
    for (int l = 0; l < n; ++l) {
        int r = l + n - 1;
        unsigned long long cur_hash = (hashes[r + 1] + m - hashes[l]) % m;
        if (cur_hash == hash_value) {
            int changes = 0;
            for (int i = 0; i < n; ++i) {
                if (s[i] != t[l + i]) {
                    changes++;
                }
            }
            ans = min(ans, changes);
        }
    }
    return ans;
}

int main()
{
    string s = "abcde";
    int ans = min_changes(s);
    cout << ans << endl;
    return 0;
}

这个程序首先计算了原始字符串的哈希值,然后枚举旋转的位置,计算新的字符串的哈希值,如果新的字符串的哈希值与旧的字符串的哈希值相同,则说明旋转后的字符串与原始字符串相同。最后,程序计算最小更改字符的数量,并返回答案。

总结

本文介绍了如何最小化要更改的字符以使字符串的左右旋转相同。这是一个非常实用的算法问题,涉及到了字符串和哈希的知识。我们介绍了使用哈希来计算字符串的哈希值,并枚举旋转的位置来计算新的字符串的哈希值。我们还介绍了如何计算最小更改字符的数量。