標籤:
1.問題:一個m個字元的字串,‘迴圈’ 向左或向右移動n(n <= m)位,求移動後的字串。例如abcdefg 左迴圈移動3位 -> defgabc, 又迴圈移動三位 -> efgabcd.
2.實現方法很多,最直接但是效率很低的方法是挨個移動字元元素,類似移動數組。這裡介紹一個技巧來實現, 以迴圈左移n位為例:
1).首先翻轉前n位,此時你可以伸出右手,手心對著你自己,假設此時從無名指到大拇指標號為1,2,3,4,5;然後翻轉你的右手,讓手心對外,則此時為5,4,3,2,1。翻轉前n位字串的過程與此類似。
那麼程式中這個過程如何?呢,很簡單,就是第一位和最後以為對換,第二位和倒數第二位對換,依次類推,實現代碼如下:
static voidswap(char &a, char &b){ a = a ^ b; b = a ^ b; a = a ^ b;}static void move(char *str, int head, int tail){ if (str == NULL || strlen(str) < 2) { return; } for (; head < tail; head++, tail--) { swap(*(str + head), *(str + tail)); }}
2).將n+1到m位翻轉,過程與上邊類似。當然這兩個翻轉執行順序沒有先後的區別。
3).將字串整體翻轉後,便得到迴圈左移後的字串。
迴圈右移的過程於此類似。
3.下面貼出可以選擇迴圈左移和右移的代碼(move.c),讀者可以參考這理解:
#include <stdio.h>#include <stdlib.h>#include <string.h>static voidswap(char &a, char &b){ a = a ^ b; b = a ^ b; a = a ^ b;}static void move(char *str, int head, int tail){ if (str == NULL || strlen(str) < 2) { return; } for (; head < tail; head++, tail--) { swap(*(str + head), *(str + tail)); }}intmain(int argc, char *argv[]){ char str[100] = { 0 }; int movenum; char direc; while(1) { printf("Enter a string And move direction(L or R) And a move num\n"); if (scanf("%s %c %d", str, &direc, &movenum) == 3) { if (movenum < 0 || movenum > strlen(str)) { printf("error\n"); continue; } printf("Before Move: %s \n", str); if (‘R‘ == direc) { //the sequence of two move op can be changed move(str, strlen(str) - movenum, strlen(str) - 1); move(str, 0, strlen(str) - movenum - 1); } else if (‘L‘ == direc) { //the sequence of two move op can be changed move(str, 0, movenum - 1); move(str, movenum, strlen(str) - 1); } else { continue; } move(str, 0, strlen(str) - 1); printf("After Move: %s \n", str); } else { break; } } return 0;}
編譯命令: g++ -g -o move move.c;,運行: ./move
部分運行結果:
當讓只是簡單的樣本程式,如果代碼出錯,歡迎指正, 同時若有更好的方法,希望不吝賜教。
雜題之迴圈移動字串