📌  相关文章
📜  使用三重循环移位按字典顺序对字符串进行排序

📅  最后修改于: 2021-05-04 20:39:24             🧑  作者: Mango

给定一个由前N个不同字母组成的字符串,任务是使用最多N / 2个移动对字符串进行排序。每一步都涉及以下内容:

  • 选择任意3个不同的索引。
  • 在这些索引处的字母上执行循环移位。

如果可以对字符串进行排序,请打印所需移动的计数。否则,打印“不可能”

例子:

方法:
为了解决问题,请按照以下步骤操作:

  • 将表示字符串字符正确的整数存储在向量中。
  • 正确放置所有可以在一个周期内占据正确索引的元素。
  • 遍历向量的元素
  • 如果元素不在其排序的索引位置,请检查是否可以在一个循环中将两个或多个数字放置在正确的索引处。如果满足条件,则执行循环,否则检查是否存在不包含正确的可用元素的独特索引。如果满足条件,则选择该索引作为循环的第三个索引并执行循环。如果以上条件均不满足,则将无法进行分类。因此,请跳出循环并打印“不可能”。
  • 一旦执行了循环移位,请存储该移位中涉及的索引
  • 如果元素处于其排序位置,则移至下一个索引。
  • 对所有矢量元素重复上述两个步骤。
  • 遍历完成后,如果整个数组按排序顺序,请打印所需的移位。否则打印“不可能”。

下面是上述方法的实现:

C++
// C++ Program for sorting a
// string using cyclic shift
// of three indices
#include 
using namespace std;
 
void sortString(vector& arr, int n,
                int moves)
{
 
    // Store the indices
    // which haven't attained
    // its correct position
    vector pos;
    // Store the indices
    // undergoing cyclic shifts
    vector > indices;
 
    bool flag = false;
 
    for (int i = 0; i < n; i++) {
 
        // If the element is not at
        // it's correct position
        if (arr[i] != i) {
 
            // Check if all 3 indices can be
            // placed to respective correct
            // indices in a single move
            if (arr[arr[arr[i]]] == i
                && arr[arr[i]] != i) {
 
                int temp = arr[arr[i]];
                indices.push_back({ i, arr[i],
                                    arr[arr[i]] });
                swap(arr[i], arr[arr[i]]);
                swap(arr[i], arr[temp]);
            }
        }
 
        // If the i-th index is still
        // not present in its correct
        // position, store the index
        if (arr[i] != i) {
            pos.push_back(i);
        }
    }
 
    for (int i = 0; i < n; i++) {
 
        if (arr[i] != i) {
 
            int pos1 = i, pos2 = arr[i];
            int pos3 = arr[arr[i]];
 
            // To check if swapping two indices
            // places them in their correct
            // position
            if (pos3 != pos1) {
 
                indices.push_back({ pos1,
                                    pos2,
                                    pos3 });
                swap(arr[pos1], arr[pos2]);
                swap(arr[pos1], arr[pos3]);
                pos.erase(find(
                    pos.begin(),
                    pos.end(), pos2));
                pos.erase(find(
                    pos.begin(),
                    pos.end(), pos3));
 
                if (arr[pos1] == pos1) {
                    pos.erase(find(
                        pos.begin(),
                        pos.end(),
                        pos1));
                }
            }
            else {
 
                if (pos3
                    == *pos.begin()) {
 
                    if (*pos.begin()
                        != pos.back()) {
                        auto it
                            = ++pos.begin();
                        pos3 = *(it);
 
                        if (*it != pos.back()
                            && pos3 == pos2) {
                            pos3 = *(++it);
                        }
                        else if (*it == pos.back()
                                 && pos3 == pos2) {
 
                            flag = true;
                            break;
                        }
                    }
                    else {
                        flag = true;
                        break;
                    }
                }
 
                indices.push_back({ pos1, pos2,
                                    pos3 });
                swap(arr[pos1], arr[pos2]);
                swap(arr[pos1], arr[pos3]);
                pos.erase(find(
                    pos.begin(),
                    pos.end(),
                    pos2));
            }
        }
 
        if (arr[i] != i) {
            i--;
        }
    }
 
    if (flag == true
        || indices.size() > moves) {
 
        cout << "Not Possible" << endl;
    }
    else {
        cout << indices.size() << endl;
 
        // Inorder to see the indices that
        // were swapped in rotations,
        // uncomment the below code
 
        /*
        for (int i = 0; i < indices.size();
             i++) {
 
            cout << indices[i][0] << " "
                 << indices[i][1] << " "
                 << indices[i][2] << endl;
        }
       */
    }
}
 
// Driver Code
int main()
{
 
    string s = "adceb";
    vector arr;
 
    for (int i = 0; i < s.size(); i++) {
        arr.push_back(s[i] - 'a');
    }
 
    sortString(arr, s.size(),
               floor(s.size() / 2));
}


Python3
# Python3 program for sorting a
# string using cyclic shift
# of three indices
import math
 
def sortString(arr, n, moves):
     
    # Store the indices
    # which haven't attained
    # its correct position
    pos = []
     
    # Store the indices
    # undergoing cyclic shifts
    indices = []
    flag = False
     
    for i in range(n):
         
        # If the element is not at
        # it's correct position
        if (arr[i] != i):
             
            # Check if all 3 indices can be
            # placed to respective correct
            # indices in a single move
            if (arr[arr[arr[i]]] == i and
                arr[arr[i]] != i):
                temp = arr[arr[i]]
                 
                indices.append([i, arr[i],
                               arr[arr[i]]])
 
                sw = arr[i]
                arr[i] = arr[arr[i]]
                arr[sw] = sw
 
                sw = arr[i]
                arr[i] = arr[temp]
                arr[temp] = sw
 
        # If the i-th index is still
        # not present in its correct
        # position, store the index
        if (arr[i] != i):
            pos.append(i)
             
    for i in range(n):
        if (arr[i] != i):
            pos1 = i
            pos2 = arr[i]
            pos3 = arr[arr[i]]
             
            # To check if swapping two indices
            # places them in their correct
            # position
            if (pos3 != pos1):
                indices.append([pos1, pos2, pos3])
                arr[pos1], arr[pos2] = arr[pos2], arr[pos1]
                arr[pos1], arr[pos3] = arr[pos3], arr[pos1]
                 
                pos.remove(pos2)
                 
                if pos3 in pos:
                    pos.remove(pos3)
                     
                if (arr[pos1] == pos1):
                    pos.remove(pos1)
                     
            else:
                if (pos3 == pos[0]):
                    it = 0
                     
                    if (pos[0] != pos[-1]):
                        it = it + 1
                        pos3 = pos[it]
                         
                        if (pos[it] != pos[-1] and
                               pos3 == pos2):
                            it = it + 1
                            pos3 = pos[it]
                             
                        elif (pos[it] == pos[-1] and
                                 pos3 == pos2):
                            flag = True
                            break
                         
                    else:
                        flag = True
                        break
                     
                indices.append([pos1, pos2, pos3])
                arr[pos1], arr[pos2] = arr[pos2], arr[pos1]
                arr[pos1], arr[pos3] = arr[pos3], arr[pos1]
                pos.remove(pos2)
                 
        if (arr[i] != i):
            i = i - 1
             
    if (flag == True or len(indices) > moves):
        print("Not Possible")
    else:
         
        # Inorder to see the indices that
        # were swapped in rotations,
        # uncomment the below code
 
        # for i in range len(indices):
        #    print (indices[i][0],
        #           indices[i][1], indices[i][2])
        print(len(indices))
 
# Driver code
s = "adceb"
arr = []
 
for i in s:
    arr.append(ord(i) - ord('a'))
     
sortString(arr, len(s), math.floor(len(s) / 2))
 
# This code is contributed by costheta_z


输出:
1