C++固定数组删除指定元素:移除标记为-1的元素
Great question—sticking with native arrays is a fantastic way to deepen your understanding of memory layout and low-level element manipulation! Let’s break this down step by step, starting with fixing small issues in your existing code, then tackling the element removal.
Quick Fixes for Your Current Code
First, let’s clean up your multipl function to avoid undefined behavior and inefficiency:
- The function declares a return type of
intbut has noreturnstatement—change it tovoidsince it doesn’t need to return a value. - Duplicate elements in
onewill repeatedly mark the sametwo[j]as-1(harmless but wasteful). We’ll add a check to skip already marked elements. - Your logic skips cases where
one[i] == two[j]—double-check if this aligns with your requirement (iftwo[j]equals an element inone, it’s technically a multiple, so you might want to remove that condition if needed).
Solution: Removing -1 Elements from a Native Array
Native arrays have a fixed size in memory, so we can’t truly "delete" elements. Instead, we have two practical approaches:
Option 1: In-Place Modification (Shift Valid Elements Forward)
This method reuses the original array’s memory, moving all non--1 elements to the front of the array, then returns the count of valid elements.
#include <iostream> using namespace std; template<typename T, size_t N> void multipl(T(&one)[N], T(&two)[N]){ for(int i = 0; i < N; ++i){ T current = one[i]; // Skip 1 if you don't want to mark every element (since all numbers are multiples of 1) if(current == 1) continue; for(int j = 0; j < N; ++j){ // Skip already marked elements to avoid redundant work if(two[j] == -1) continue; // Check if two[j] is a multiple (adjust the != condition if needed) if(two[j] % current == 0 && two[j] != current){ two[j] = -1; } } } } template<typename T, size_t N> size_t removeMarkedElements(T(&arr)[N], T marker){ size_t validCount = 0; // Iterate through the array, moving valid elements to the front for(size_t i = 0; i < N; ++i){ if(arr[i] != marker){ arr[validCount] = arr[i]; validCount++; } } return validCount; } int main(){ int one[] = {2,5,2,5,5,11}; int two[] = {4,8,1,3,2,10}; size_t originalSize = sizeof(two)/sizeof(two[0]); // Mark elements to remove multipl(one, two); // Remove marked elements and get the count of valid elements size_t validSize = removeMarkedElements(two, -1); // Print the result cout << "Valid elements in two after removal: "; for(size_t i = 0; i < validSize; ++i){ cout << two[i] << " "; } cout << endl; return 0; }
Option 2: Create a New Array for Filtered Elements
If you want to preserve the original array, you can create a new array to store only the valid elements. Note: We’ll use a fixed-size array here; for dynamic sizing, you’d use new/delete (or smart pointers) to allocate memory at runtime.
// Add this function to the code above template<typename T, size_t N> size_t filterToArray(const T(&source)[N], T(&dest)[N], T marker){ size_t validCount = 0; for(size_t i = 0; i < N && validCount < N; ++i){ if(source[i] != marker){ dest[validCount] = source[i]; validCount++; } } return validCount; } // In main(), after calling multipl(): int filteredTwo[6]; // Same size as the original two array size_t filteredSize = filterToArray(two, filteredTwo, -1); cout << "Filtered array (original preserved): "; for(size_t i = 0; i < filteredSize; ++i){ cout << filteredTwo[i] << " "; } cout << endl;
Key Takeaways
- Native arrays can’t change their size, so you always need to track the number of valid elements separately.
- The in-place method is memory-efficient, while the new array method keeps your original data intact.
- If working with non-integer types, replace
-1with a sentinel value that won’t appear in your actual data (e.g., a special string or a default-constructed value).
内容的提问来源于stack exchange,提问作者Rob_Fir

