基础概念公式推到可参考该专栏下的前几篇博文。
菱形斜纹组织图:
分析:首先3上2下2上1下,飞数为+1,右斜。kw=8表示从左下角开始往上数8格为纬峰所在位置;kj=8表示从左上角开始往右数8格为经峰所在位置。
这样就将菱形斜纹组织图通过kw和kj分割为四部分,很明显,Ⅰ、Ⅱ部分也就是经山形组织;
一、先求第一部分(也就是规则组织求法)
1,3上2下2上1下,fw=8,fj=8,确定矩阵的大小
2,通过规则组织求法,求出第一部分
详细解法步骤内容可参考此处
实现步骤:
1,对第一列赋值
2,对第2列到第kj列赋值,需要注意,这里通过(i+f)>N1判断越界,通过a[i][j] = a[i+f-kw][j-1]越界赋值
核心代码如下:
/*
对第一部分的第1列进行赋值
*/i=1;//先对第一列赋值,从第一列的第一行开始for(j=0;j<=m-1;j++){while(c[j]>0){a[N1-i+1][1]=1;//因为是分子,所有值都赋值为1c[j]--;i++;}while(d[j]>0){a[N1-i+1][1]=0;//因为是分母,所有值都赋值为0d[j]--;i++;}}
/*
对第一部分的2到kj列 进行赋值
*/for(j=2;j<=kj;j++){for(i=kw-1;i<=N1;i++){if((i+f)>N1) a[i][j] = a[i+f-kw][j-1];else a[i][j]=a[i+f][j-1];}}/*
效果图如下:
二、求第二部分(第二部分与第一部分关于第kj根经纱完全对称
关系)
1,Ⅱ区中的任何一列都可以从Ⅰ区中对应
例如:a[14][3]==a[14][13]、a[13][4]=a[13][12]
通过推导可得公式:
2,再分别对第kj+1列到第N2列进行对称式赋值
核心代码如下:
/*
对第二部分(kj+1列到N2列)进行赋值
*/for(j=kj+1;j<=N2;j++){for(i=N1;i>=N1-kw+1;i--){a[i][j]=a[i][2*kj-j];}}
效果图如下:
三、根据第一、第二部分与第三、第四部分对称关系,求第三部分和第四部分
观察可知,第三部分和第四部分是关于kw与第一部分和第二部分对称
核心代码如下:
/*
对第三部分和第四部分进行赋值
*/for(i=1;i<=N1-kw;i++){for(j=1;j<=N2;j++){a[i][j]=a[2*(N1-kw+1)-i][j];}}
效果图如下:
代码如下:
该代码仅适用于Kw==N1情况
#include <iostream>
#include<stdio.h>
using namespace std;int main()
{int i,j,N1,N2,f,m,kj,kw;//kj表示山峰的位置,从而确定出总列数N2int c[10],d[10],a[100][100]={0};printf("please input m:");scanf("%d",&m);for(i=0;i<=m-1;i++){printf("please input C[%d]:",i+1);scanf("%d",&c[i]);printf("please input D[%d]:",i+1);scanf("%d",&d[i]);}printf("please input kj:");scanf("%d",&kj);//输入山峰位置,从而确定出总列数printf("please input kw:");scanf("%d",&kw);//输入山峰位置,从而确定出总列数N1=2*kw-2;N2=2*kj-2;printf("please input f:");scanf("%d",&f);/*
对第一部分的第1列进行赋值
*/i=1;//先对第一列赋值,从第一列的第一行开始for(j=0;j<=m-1;j++){while(c[j]>0){a[N1-i+1][1]=1;//因为是分子,所有值都赋值为1c[j]--;i++;}while(d[j]>0){a[N1-i+1][1]=0;//因为是分母,所有值都赋值为0d[j]--;i++;}}/*
对第一部分的2到kj列 进行赋值
*/for(j=2;j<=kj;j++){for(i=kw-1;i<=N1;i++){if((i+f)>N1) a[i][j] = a[i+f-kw][j-1];else a[i][j]=a[i+f][j-1];}}/*
对第二部分(kj+1列到N2列)进行赋值
*/for(j=kj+1;j<=N2;j++){for(i=N1;i>=N1-kw+1;i--){a[i][j]=a[i][2*kj-j];}}/*
对第三部分和第四部分进行赋值
*/for(i=1;i<=N1-kw;i++){for(j=1;j<=N2;j++){a[i][j]=a[2*(N1-kw+1)-i][j];}}/*
输出二维数组a[i][j]
*/for(i=1;i<=N1;i++){for(j=1;j<=N2;j++){printf("%5d",a[i][j]);}printf("\n");}getchar();return 0;
}
最终运行效果如下:
补充:实际上菱形斜纹组织的Kw并不一定都等于组织循环数,至于大于或者小于组织循环数的按照Kw进行忽略不显示。
例如:3上2下2上1下,右斜,飞数为1,Kw=5,Kj=5
此时组织循环数为3+2+2+1=8,小于Kw,如何处理?
实际上,当Kw小于组织循环数时,超过Kw的组织会被忽略但是不会消失,遇到顶部时仍会从下上来。
灰色部分表示超过Kw的部分,会被忽略但是不会消失。
如上图部分为第一部分,其余部分都可以根据对称来进行求解,主要就是第一部分元素的确定
如何确定呢?
我的思路为:
主要就是第一部分的求解很重要,但是他会忽略超过Kw的区域,于是我想到了通过两个二维数组进行求解,首先第一个二维数组专门用于求解第一部分的数值,直接通过输入的组织循环数和飞数来获取规则组织。
然后通过第二个二维数组截取通过Kw和Kj所确定出的第一部分的元素,之后第二个二维数组就存有第一部分的元素了,再通过对称的方法求解出第二第三第四部分的元素即可。
优化后的代码如下:
#include <iostream>
#include<stdio.h>
using namespace std;int main()
{int i,j,N1,N2,n1,n2,f,m,kj,kw;int c[10],d[10],a[100][100]={0},b[100][100]={0};printf("please input m:");scanf("%d",&m);for(i=0;i<=m-1;i++){printf("please input C[%d]:",i+1);scanf("%d",&c[i]);printf("please input D[%d]:",i+1);scanf("%d",&d[i]);}printf("please input kj:");scanf("%d",&kj);//输入山峰位置printf("please input kw:");scanf("%d",&kw);//输入山峰位置n1=2*kw-2;//n1和n2才是最终的二维数组大小n2=2*kj-2;N1=0;for(i=0;i<=m-1;i++){N1=N1+c[i]+d[i];}N2=N1;printf("please input f:");scanf("%d",&f);/*
对第一部分的第1列进行赋值
*/i=1;//先对第一列赋值,从第一列的第一行开始for(j=0;j<=m-1;j++){while(c[j]>0){a[N1-i+1][1]=1;//因为是分子,所有值都赋值为1c[j]--;i++;}while(d[j]>0){a[N1-i+1][1]=0;//因为是分母,所有值都赋值为0d[j]--;i++;}}
/*
对2到N1列 进行赋值
*/for(j=2;j<=N2;j++){for(i=1;i<=N1;i++){if((i+f)>N1) a[i][j] = a[i+f-N1][j-1];else a[i][j]=a[i+f][j-1];}}
/*
对第一部分结果的有效部分赋给数组b
*/for(i=0;i<kw;i++){for(j=0;j<kj;j++){b[kw-1+i][1+j]=a[N1-kw+1+i][1+j];}}//对第二部分(kj+1列到N2列)进行赋值for(j=kj+1;j<=n2;j++){for(i=n1;i>=n1-kw+1;i--){b[i][j]=b[i][2*kj-j];}}//对第三部分和第四部分进行赋值for(i=1;i<=n1-kw;i++){for(j=1;j<=n2;j++){b[i][j]=b[2*(n1-kw+1)-i][j];}}/*
输出二维数组b[i][j]
*/for(i=1;i<=n1;i++){for(j=1;j<=n2;j++){printf("%5d",b[i][j]);}printf("\n");}getchar();return 0;
}
运行效果如下: