[英]Left Shift/ Right Shift an array using two pointers in C
我正在嘗試對數組實現左移/右移。
我能夠使用雙循環完成此操作。 我可以得到一些幫助來提高效率嗎?
這是使用 2 個循環的 LeftShift/RightShift 的工作代碼。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
struct Array
{
int A[10];
int size;
int length;
};
void Display(struct Array arr)
{
printf("\nElements are : \n");
for(int i = 0;i<arr.length;i++)
printf("%d ", arr.A[i]);
}
// Left Shift-------------------------------------------------------------------------------------------------------
void LeftShift1(struct Array *arr, int n) //n is the number of shifts
{
int temp = arr->A[0];
for(int i=0; i<n; i++)
{
for(int j=0; j<arr->length-1; j++)
{
arr->A[j] = arr->A[j+1];
}
arr->A[arr->length-1] = 0;
}
}
//Right Shift-------------------------------------------------------------------------------------------------------
void RightShift(struct Array *arr, int n) //n is the number of shifts
{
for(int i = 0; i<n; i++)
{
for(int j=arr->length-1; j>0; j--)
{
arr->A[j] = arr->A[j-1];
}
arr->A[0] = 0;
}
}
int main()
{
struct Array arr={{1,2,3,4,5},10,5};
LeftShift1(&arr, 2);
//RightShift(&arr, 1);
Display(arr);
return 0;
}
我正在嘗試這樣的事情,它使用 2 個迭代器來解決這個問題!
這也有效!
void LeftShift2(struct Array *arr, int n)
{
for(int k=0; k<n; k++)
{
int i,j;
for(i=0, j=0; j<arr->length-1; i++, j++)
{
arr->A[j] = arr->A[j+1];
}
arr->A[arr->length-1] = 0;
}
}
但這可以在沒有循環的情況下解決嗎? 還是用一個循環?
這可以提高效率嗎?
一些幫助提高效率?
移位:移位一次。 從O(n*length)
到O(length)
。
輪換:一次轉變為臨時。 從O(n*length)
到O(length)
。
首先確定尺寸數量。
void LeftShift_alt(struct Array *arr, int n) {
if (n > arr->length) {
n = arr->length;
}
memmove(arr, arr + n, sizeof *arr * (arr->length - n));
memset(arr + n, 0, sizeof *arr * n);
}
void LeftRotate_alt(struct Array *arr, int n) {
if (arr->length > 0) {
n %= arr->length;
if (n > 0) {
int temp[n];
memcpy(temp, arr, sizeof temp);
memmove(arr, arr + n, sizeof *arr * (arr->length - n));
memcpy(arr + n, temp, sizeof temp);
}
}
}
如果需要,將mem...()
替換為指針代碼。
您可以在結構中提供所有常見的訪問運算符(<<、>>、[] 等),而不是實際移動數組的內容。 (假設您使用的是支持此功能的編譯器。否則,您將需要創建 C 風格的這些函數。)如果有人這樣做:
my_array <<= 5;
my_array >>= 2;
...您只需跟蹤數組已移動了多少。 在這種情況下,他們總共向左移動了 3 個位置。 當有人索引到數組中時,您將累積的偏移量添加到他們的索引(以數組的大小為模)以獲取他們正在尋找的條目的實際位置。 這使得移位 O(1) 而不是 O(n)。 如果您正在尋找一種有效的解決方案,那么這已經足夠了。
CODE REVIEW
:
在 C 中,可以通過使用單個循環來提高效率。 我們可以將元素移動n
個位置,而不是一次移動一個位置!
像這樣的東西:
void LeftShift1(struct Array* arr, unsigned int n) {
if (n > arr->length) {
n = arr->length;
}
for (unsigned int i = 0; i < arr->length; i++) {
if (i + n < arr->length)
arr->A[i] = arr->A[i + n];
else
arr->A[i] = 0;
}
}
在實際使用中,我們會考慮使用除普通int
以外的元素類型進行數組移位。 事實上,它可能是一個像string
一樣的復雜類型,我們不應該對字符串進行原始的memcpy
。
在我的代碼中,我將移出的元素設置為 0,這對於整數和相關類型是可以的,但它在字符串中不會類似地工作。
從 C++20 開始,有一個標准的std::shift_left
和std::shift_right
可供使用。 還有std::rotate
可用於旋轉元素。
int arr[] = {1,2,3,4,5};
using std::ranges::begin;
using std::ranges::end;
std::shift_left (begin(arr),end(arr),2);
Display(arr);
同樣在 C++ 中,我們應該使用像vector
這樣的靈活容器來代替struct
!
此外,如果我們在兩端進行大量添加和刪除元素,那么有一個專門為稱為deque
(“雙端隊列”)而設計的容器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.