我必须用C语言来解决它。我有 n 个整数的数组。 L 和 U 是下限和上限。我必须反转 [L,U] 数组中的数字。我尝试过这种方式,但在某些情况下答案是错误的。代码中需要更改哪些内容?或者还有其他逻辑来完成任务吗?
#include <stdio.h>
int main() {
int x, arr[100], n, l, u, a, temp, temp1;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
}
a = n / 2;
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
输入示例: 10(整数个数) -7(下限) 5(上限) -10 -9 5 -2 -3 7 10 6 -8 -5
输出示例: -10 -9 -5 -3 -2 7 10 6 -8 5
我的输出: -10 -9 -5 -2 -3 7 10 6 -8 5
有一个
O(N)
解决方案,不需要嵌套循环。
首先,使用现有的代码,声明一个附加数组和一些其他辅助变量,用于跟踪需要交换的索引。
int left, right;
int swaplist[100] = {0};
int swapcount = 0;
您可以完全保持初始摄入循环,但如果该值位于下限和上限之间,则进行修改以将新扫描值的 index 附加到
swaplist
数组。
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
if ((x >= l) && (x <= u)) {
swaplist[swapcount++] = i;
}
}
然后用一个循环迭代“swaplist”并对原始数组进行交换。
left = 0;
right = swapcount-1;
while (left < right) {
int leftindex = table[left];
int rightindex = table[right];
int tmp = arr[leftindex];
arr[leftindex] = arr[rightindex];
arr[rightindex] = tmp;
left++; right--;
}
你做出了勇敢的尝试。您的嵌套
for()
循环适用于某些排序算法,但不适用于此任务的目的。
根据样本输入和所需的输出,您确实希望在数组的两端建立一个“括号”,然后将两者向中心移动,交换值恰好满足
low <= n <= high
值的元素。 (在这种情况下,-7 <= n <= 5).
解决方案如下:
#include <stdio.h>
int swap( int arr[], size_t l, size_t r ) { // conventional swap algorithm
int t = arr[l];
arr[l] = arr[r];
arr[r] = t;
return 1;
}
int main() {
int arr[] = { -10, -9, 5, -2, -3, 7, 10, 6, -8, -5, }; // your data
size_t i, sz = sizeof arr/sizeof arr[0];
for( i = 0; i < sz; i++ ) // showing original version
printf( "%d ", arr[i] );
putchar( '\n' );
#define inRange( x ) ( -7 <= arr[x] && arr[x] <= 5 ) // a good time for a macro
size_t L = 0, R = sz - 1; // 'L'eft and 'R'ight "brackets"
do {
while( L < R && !inRange( L ) ) L++; // scan from left to find a target
while( L < R && !inRange( R ) ) R--; // scan from right to find a target
} while( L < R && swap( arr, L, R ) && (L+=1) > 0 && (R-=1) > 0 );
for( i = 0; i < sz; i++ ) // showing results
printf( "%d ", arr[i] );
putchar( '\n' );
return 0;
}
-10 -9 5 -2 -3 7 10 6 -8 -5
-10 -9 -5 -3 -2 7 10 6 -8 5
如果我正确理解了赋值,那么您需要反转满足某些条件的数组元素。
如果是这样,那么这些嵌套的 for 循环
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
没有道理。
只需使用一个for循环就足够了,如下面的演示程序所示。
#include <stdio.h>
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int l = 10, u = 50;
for (size_t i = 0, j = N; i < j; i++ )
{
while (i < j && !( l <= a[i] && a[i] <= u )) ++i;
if (i < j)
{
while (i < --j && !( l <= a[j] && a[j] <= u ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
程序输出为
1 10 2 3 20 4 30 5 40 6 7 50 9
1 50 2 3 40 4 30 5 20 6 7 10 9
您可以编写一个单独的函数,例如
#include <stdio.h>
void reverse_in_range( int a[], size_t n, int low, int upper )
{
for (size_t i = 0, j = n; i < j; )
{
while (i < j && !( low <= a[i] && a[i] <= upper )) ++i;
if (i < j)
{
while (i < --j && !( low <= a[j] && a[j] <= upper ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
++i;
}
}
}
}
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
reverse_in_range( a, N, 10,50 );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
感谢大家的帮助。我读了所有这些,但我找到了另一种方法来解决这个问题。我会写它以防万一。 (一些变量名称是随机的,因此如有疑问,请评论)。
#include <stdio.h>
int main() {
int x, main[100], n, l, u, a = 0, arr[100], temp, m = 0,f=0,c,d;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
main[i] = x;
if (x >= l && x <= u) {
a++; //check if element is in range [l,u] and increasing a. later "a" will be used a length of the array "arr". this array cootains elements, which in in [u,l].
}
}
//add [u,l] elements in new array "arr"
for (int i = 0; i < n; i++) {
if (main[i] >= l && main[i] <= u) {
arr[m] = main[i];
m++; //index counter of "arr",
}
}
d=0;
for(int i=0;i<n;i++){
if(main[i]==arr[d]){
c=arr[a-d-1];
main[i]=c;
d++;
}
}
for(int i=0;i<n;i++){
printf("%d ",main[i]);
}
}
这个功能应该可以用
/**
* reverse_array - reverses an array
* @a: pointer to array
* @n: variable for array size
*/
void reverse_array(int *a, int n)
{
int length = 0, length1, length2, actlength = n - 1;
int arr[100];
for (length1 = 0, length2 = 0; length1 < n; length1++, length2++)
arr[length1] = a[length2];
if (n > 0)
{
while (length < n)
{
a[length] = arr[actlength];
actlength--;
length++;
}
}
}
我最好的猜测是 scanf 非常烦人,最重要的是,你的格式不明确。
%d%d%d 将如何读取 1234?它会给你 12 3 和 4 吗? 1 23 和 4? ...
尝试去做
scanf("%d %d %d" ...); // or
scanf("%d, %d, %d" ...);
类似的事情。请注意,不建议使用 scanf,getc 是一个巧妙的替代方案,尽管当您想要读取多于一位数字的数字时也很烦人,但您可以创建一个函数 read_number,该函数基于 getc,将读取数字为一个字符串并用 stoi 返回 int 值。