📜  允许奇数和偶数变化的不同字符串

📅  最后修改于: 2021-10-27 16:52:34             🧑  作者: Mango

给定一个小写字符串数组,任务是找到不同字符串的数量。如果在对一个字符串应用以下操作时无法形成第二个字符串,则两个字符串是不同的。

  • 在奇数索引中的字符可以与仅在奇数索引的另一字符被交换。
  • 关于偶数的索引中的字符可以与只有偶数的索引其他字符进行互换。

例子:

Input  : arr[] = {"abcd", "cbad", "bacd"}
Output : 2
The 2nd string can be converted to the 1st by swapping 
the first and third characters. So there are 2 distinct 
strings as the third string cannot be converted to the 
first.

Input  : arr[] = {"abc", "cba"}
Output : 1 

一个简单的解决方案是运行两个循环。外循环选择一个字符串,内循环检查是否存在可以通过执行允许的转换将其转换为当前字符串的先前字符串。此解决方案需要 O(n 2 m) 时间,其中 n 是字符串的数量,而 m 是任何字符串的最大字符数。

有效的解决方案产生用于每一个输入字符串的编码字符串。编码具有由分隔符分隔的偶数和奇数定位字符的计数。如果两个字符串的编码字符串相同,则认为它们是不同的,否则就不是。一旦我们有了对字符串进行编码的方法,问题就归结为计算不同的编码字符串。这是一个典型的散列问题。我们创建一个散列集,并一个一个地存储字符串的编码。如果编码已经存在,我们忽略字符串。否则,我们将编码存储在哈希中并增加不同字符串的计数。

C++
#include
using namespace std;
 
int MAX_CHAR = 26;
 
    string encodeString(char str[], int m) {
        // hashEven stores the count of even indexed character
        // for each string hashOdd stores the count of odd
        // indexed characters for each string
        int hashEven[MAX_CHAR];
        int hashOdd[MAX_CHAR];
 
        // creating hash for each string
        for (int i = 0; i < m; i++) {
            char c = str[i];
            if ((i & 1) != 0) // If index of current character is odd
                hashOdd[c-'a']++;
            else
                hashEven[c-'a']++;
 
        }
 
 
        // For every character from 'a' to 'z', we store its
        // count at even position followed by a separator,
        // followed by count at odd position.
        string encoding = "";
        for (int i = 0; i < MAX_CHAR; i++) {
            encoding += (hashEven[i]);
            encoding += ('-');
            encoding += (hashOdd[i]);
            encoding += ('-');
        }
        return encoding;
    }
 
    // This function basically uses a hashing based set to
// store strings which are distinct according to according
// to criteria given in question.
    int countDistinct(string input[], int n) {
        int countDist = 0; // Initialize result
 
        // Create an empty set and store all distinct
        // strings in it.
        set s;
        for (int i = 0; i < n; i++) {
            // If this encoding appears first time, increment
            // count of distinct encodings.
              char char_array[input[i].length()+1];
              strcpy(char_array, input[i].c_str());
            if (s.find(encodeString(char_array, input[i].length()+1)) == s.end()) {
                s.insert(encodeString(char_array,input[i].length()+1));
                countDist++;
            }
        }
 
        return countDist;
    }
 
// Driver code
    int main() {
        string input[] = {"abcd", "acbd", "adcb", "cdba",
                "bcda", "badc"};
        int n = sizeof(input)/sizeof(input[0]);
 
        cout << countDistinct(input, n) << "\n";
    }
 
// This code is contributed by NishaBharti.


Java
// Java program to count distinct strings with
// even odd swapping allowed.
import java.util.HashSet;
import java.util.Set;
class GFG {
static int MAX_CHAR = 26;
 
    static String encodeString(char[] str) {
        // hashEven stores the count of even indexed character
        // for each string hashOdd stores the count of odd
        // indexed characters for each string
        int hashEven[] = new int[MAX_CHAR];
        int hashOdd[] = new int[MAX_CHAR];
 
        // creating hash for each string
        for (int i = 0; i < str.length; i++) {
            char c = str[i];
            if ((i & 1) != 0) // If index of current character is odd
                hashOdd[c-'a']++;
            else
                hashEven[c-'a']++;
 
        }
 
 
        // For every character from 'a' to 'z', we store its
        // count at even position followed by a separator,
        // followed by count at odd position.
        String encoding = "";
        for (int i = 0; i < MAX_CHAR; i++) {
            encoding += (hashEven[i]);
            encoding += ('-');
            encoding += (hashOdd[i]);
            encoding += ('-');
        }
        return encoding;
    }
 
    // This function basically uses a hashing based set to
// store strings which are distinct according to according
// to criteria given in question.
    static int countDistinct(String input[], int n) {
        int countDist = 0; // Initialize result
 
        // Create an empty set and store all distinct
        // strings in it.
        Set s = new HashSet<>();
        for (int i = 0; i < n; i++) {
            // If this encoding appears first time, increment
            // count of distinct encodings.
            if (!s.contains(encodeString(input[i].toCharArray()))) {
                s.add(encodeString(input[i].toCharArray()));
                countDist++;
            }
        }
 
        return countDist;
    }
 
    public static void main(String[] args) {
        String input[] = {"abcd", "acbd", "adcb", "cdba",
                "bcda", "badc"};
        int n = input.length;
 
        System.out.println(countDistinct(input, n));
    }
}


Python3
# Python3 program to count distinct strings with
# even odd swapping allowed.
MAX_CHAR = 26
 
# Returns encoding of string that can be used
# for hashing. The idea is to return same encoding
# for strings which can become same after swapping
# a even positioned character with other even characters
# OR swapping an odd character with other odd characters.
def encodeString(string):
 
    # hashEven stores the count of even indexed character
    # for each string hashOdd stores the count of odd
    # indexed characters for each string
    hashEven = [0] * MAX_CHAR
    hashOdd = [0] * MAX_CHAR
 
    # creating hash for each string
    for i in range(len(string)):
        c = string[i]
        if i & 1: # If index of current character is odd
            hashOdd[ord(c) - ord('a')] += 1
        else:
            hashEven[ord(c) - ord('a')] += 1
 
    # For every character from 'a' to 'z', we store its
    # count at even position followed by a separator,
    # followed by count at odd position.
    encoding = ""
    for i in range(MAX_CHAR):
        encoding += str(hashEven[i])
        encoding += str('-')
        encoding += str(hashOdd[i])
        encoding += str('-')
 
    return encoding
 
# This function basically uses a hashing based set to
# store strings which are distinct according to according
# to criteria given in question.
def countDistinct(input, n):
    countDist = 0 # Initialize result
 
    # Create an empty set and store all distinct
    # strings in it.
    s = set()
    for i in range(n):
 
        # If this encoding appears first time, increment
        # count of distinct encodings.
        if encodeString(input[i]) not in s:
            s.add(encodeString(input[i]))
            countDist += 1
 
    return countDist
 
# Driver Code
if __name__ == "__main__":
    input = ["abcd", "acbd", "adcb",
             "cdba", "bcda", "badc"]
    n = len(input)
    print(countDistinct(input, n))
 
# This code is contributed by
# sanjeev2552


C#
// C# program to count distinct strings with
// even odd swapping allowed.
using System;
using System.Collections.Generic;
     
class GFG
{
    static int MAX_CHAR = 26;
 
    static String encodeString(char[] str)
    {
        // hashEven stores the count of even
        // indexed character for each string
        // hashOdd stores the count of odd
        // indexed characters for each string
        int []hashEven = new int[MAX_CHAR];
        int []hashOdd = new int[MAX_CHAR];
 
        // creating hash for each string
        for (int i = 0; i < str.Length; i++)
        {
            char m = str[i];
             
            // If index of current character is odd
            if ((i & 1) != 0)
                hashOdd[m - 'a']++;
            else
                hashEven[m - 'a']++;
        }
 
        // For every character from 'a' to 'z',
        // we store its count at even position
        // followed by a separator,
        // followed by count at odd position.
        String encoding = "";
        for (int i = 0; i < MAX_CHAR; i++)
        {
            encoding += (hashEven[i]);
            encoding += ('-');
            encoding += (hashOdd[i]);
            encoding += ('-');
        }
        return encoding;
    }
 
    // This function basically uses a hashing based set
    // to store strings which are distinct according
    // to criteria given in question.
    static int countDistinct(String []input, int n)
    {
        int countDist = 0; // Initialize result
 
        // Create an empty set and store all distinct
        // strings in it.
        HashSet s = new HashSet();
        for (int i = 0; i < n; i++)
        {
            // If this encoding appears first time,
            // increment count of distinct encodings.
            if (!s.Contains(encodeString(input[i].ToCharArray())))
            {
                s.Add(encodeString(input[i].ToCharArray()));
                countDist++;
            }
        }
 
        return countDist;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String []input = {"abcd", "acbd", "adcb",
                          "cdba", "bcda", "badc"};
        int n = input.Length;
 
        Console.WriteLine(countDistinct(input, n));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


输出

4

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程